在 Rust 中将构造的字符串插入 Vec

Insert constructed string into Vec in Rust

现在我正在编写一个程序,我正在使用基于 for 循环中的条件构造的字符串更新 Vec。我正在尝试做的(非常人为的)简化形式如下:

fn main() {
    let mut arr = vec!["_"; 5];
    for (i, chr) in "abcde".char_indices() {
        arr[i] = &chr.to_string().repeat(3);
    }
}

但是,我收到错误 temporary value dropped while borrowed。关于在这里做什么的任何指示?

问题是arr只持有引用,里面的字符串必须在别处拥有。一个可能的解决方法是简单地泄漏您在循环中创建的瞬态字符串。

fn main() {
    let mut arr = vec!["_"; 5];
    for (i, chr) in "abcde".char_indices() {
        arr[i] = Box::leak(Box::new(chr.to_string().repeat(3)));
    }
}

arr的生命周期是main方法的范围,而chr.to_string()只在for循环体中有效。分配它会导致错误。

您可以使用 Vec<String> 而不是 Vec<&str> 来避免此问题。

fn main() {
  let mut arr = vec!["_".to_string(); 5];
  for (i, chr) in "abcde".char_indices() {
    arr[i] = chr.to_string().repeat(3);
  }
}

这里我们看到 String "_".to_string() 被复制了五次(效率不高)。我怀疑您的真实代码并非如此。

使用字符串也尝试 this 一个衬里:

let arr: Vec<String> = "abcde".chars().map(|c| c.to_string().repeat(3)).collect();

输出:

["aaa", "bbb", "ccc", "ddd", "eee"]

正如其他人所提到的,您正在创建的 String 必须 由某人拥有,否则它们最终会被丢弃。当编译器检测到这种删除发生时您的数组仍然保留对它们的引用,它会抱怨。

你需要考虑谁需要拥有这些价值。如果您最终的阵列是他们居住的自然场所,那么 move 他们就在那里:

fn main() {
    let mut arr = Vec::with_capacity(5);
    for (i, chr) in "abcde".char_indices() {
        arr.push(chr.to_string().repeat(3));
    }
}

如果您绝对需要 &str 的数组,您仍然需要维护这些值 'alive' 至少与引用本身一样长:

fn i_only_consume_refs(data: Vec<&String>) -> () {}

fn main() {
    let mut arr = Vec::with_capacity(5);
    for (i, chr) in "abcde".char_indices() {
        arr.push(chr.to_string().repeat(3));
    }
    let refs = arr.iter().collect();
    i_only_consume_refs(refs)
}

在这里,我们仍然将所有创建的 String 移动到向量 arr,然后引用其元素。这样,只要 arr (谁拥有字符串),引用向量就有效。

TL;DR:有人需要拥有这些 String,而您保留对它们的引用。你不能创建临时字符串,只存储引用,否则你将引用一个被丢弃的值,这确实很糟糕,编译器不会让你这样做。