string - 用同一向量 Rust 中的另一个字符串扩展一个字符串

标签 string vector rust

我是 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/

相关文章:

c++ - 如何有效地从给定另一个 vector 的 vector 中删除元素

c++ - 错误 : No instance of constructor "Faktura::Faktura" matches the argument list

rust - 是否有从 stdin 或 rust 文件中读取的特征?

ios - 多行 NSAttributed 字符串作为 UIButton 标题

java - 通过标记分割字符串?

r - 带特殊字符的grep

javascript - 将数字从字符串替换为对象

Java vector : Secure reference to element

rust - 为什么编译器声称来自更高级别特征绑定(bind)的关联类型没有实现 `Display` ,即使它应该实现?

rust - 如何实现安全的全局实例?