我是 Rust 新手,我无法解决这个简单的问题: 考虑以下代码:
let mut a = vec![String::from("aa"), String::from("bb")];
a[0] += &*a[1];
借用检查器正确地提示我在这里同时具有不可变借用和可变借用。它还建议我:
help: try adding a local storing this...
--> src\main.rs:61:15
|
61 | a[0] += &*a[1];
| ^^^^
help: ...and then using that local here
--> src\main.rs:61:5
|
61 | a[0] += &*a[1];
| ^^^^^^^^^^^^^^
我不太明白这是什么意思。我真的需要克隆字符串来执行如此简单的操作吗? (这将导致 2 个整体副本:进入临时副本,然后返回到 a[0],而不是直接将最佳副本复制到 [0])
最佳答案
天真地,像这样(没有理由取消引用a[1]
):
fn main() {
let mut a = vec![String::from("aa"), String::from("bb")];
a[0] += &a[1];
}
遗憾的是,正如您所注意到的,这会给借用检查器带来问题。修改 a[0]
会可变地借用它,同时您还需要不变地借用 a[1]
来附加它。并且不允许同时借用可变和不可变的a
:
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
--> src/main.rs:3:14
|
3 | a[0] += &a[1];
| ---------^---
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| mutable borrow later used here
原因是 Rust 不知道 a[0]
和 a[1]
是独立变量。此行为是有意为之且重要的,因为它可以防止某些可能导致未定义行为的情况。 Rust 具有零未定义行为保证。
不过,您可以通过 split_at_mut 函数将数组拆分为两个独立的可变部分。这是可行的,因为 Rust 现在可以保证两个部分都是独立的。按顺序借用它们使得(当前的)Rust 无法证明这一点。
fn main() {
let mut a = vec![String::from("aa"), String::from("bb")];
let (a_left, a_right) = a.split_at_mut(1);
a_left[0] += &a_right[0];
println!("{:?}", a);
}
["aabb", "bb"]
请注意,split_at_mut
几乎是免费的。它实际上并不复制任何内容,它只是创建两个指向数组的两个不重叠部分的切片。它不会导致任何性能开销。
关于string - 用同一向量 Rust 中的另一个字符串扩展一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74592882/