Rust中如何转换字符串切片容器?解决借用冲突问题
Rust字符串切片转换的单循环解决方案
现有一个Vec<&str>类型的容器(无法修改该类型),需要对其中每个字符串做转换处理。由于切片不持有字符串所有权,必须把转换后的字符串存储到某个容器中。最初尝试用VecDeque实现单循环处理,写出了如下代码:
use std::collections::VecDeque; fn transform(s: &str) -> String { s.to_owned() + "blah" } pub fn func<'a>(strings: &mut Vec<&'a str>, string_storage: &'a mut VecDeque<String>) { for string in strings.iter_mut() { string_storage.push_back(transform(string)); *string = string_storage.back().unwrap().as_str(); } }
这段代码触发了error[E0502]: cannot borrow *string_storage as mutable because it is also borrowed as immutable错误,原因是同一循环内,先对string_storage做了可变借用(push_back操作),紧接着又通过back()做了不可变借用,Rust的借用检查器不允许这种同时存在的可变与不可变借用。
简洁的单循环解决方案
方案一:使用Vec+预分配+索引访问
fn transform(s: &str) -> String { s.to_owned() + "blah" } pub fn func<'a>(strings: &mut Vec<&'a str>, string_storage: &'a mut Vec<String>) { // 预分配足够空间,避免循环中扩容导致索引失效 string_storage.reserve(strings.len()); for (i, string) in strings.iter_mut().enumerate() { string_storage.push(transform(string)); // 通过索引访问刚插入的元素,避免同时借用容器的可变/不可变引用 *string = string_storage[i].as_str(); } }
方案二:使用VecDeque+索引访问
use std::collections::VecDeque; fn transform(s: &str) -> String { s.to_owned() + "blah" } pub fn func<'a>(strings: &mut Vec<&'a str>, string_storage: &'a mut VecDeque<String>) { string_storage.reserve(strings.len()); for string in strings.iter_mut() { let idx = string_storage.len(); string_storage.push_back(transform(string)); // 利用插入前的长度作为新元素的索引,直接访问 *string = string_storage[idx].as_str(); } }
这两种方案都只需要一次遍历即可完成转换与赋值,核心思路是避免在可变借用容器后直接调用back()这类会产生容器不可变引用的方法,转而通过索引访问新插入的元素。提前调用reserve预分配空间,可以避免容器扩容导致的索引失效问题,保证代码的安全性。
内容的提问来源于stack exchange,提问作者LHLaurini
相关产品推荐
相关产品推荐

