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

Rust 将构造字符串插入生锈的Vec中,rust,lifetime,Rust,Lifetime,现在我正在编写一个程序,其中我正在使用基于for循环中的条件构造的字符串更新Vec。我试图做的(非常做作的)简化形式如下: fn main(){ 让mut arr=vec![“5]; 对于“abcde”中的(i,chr)。char_索引(){ arr[i]=&chr.to_string()。重复(3); } } 但是,我在借用时删除了错误临时值。这里有什么指示吗?问题是arr只保存引用,其中的字符串必须在其他地方拥有。一个可能的修复方法是简单地泄漏在循环中创建的临时字符串 fn main()

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

fn main(){
让mut arr=vec![“5];
对于“abcde”中的(i,chr)。char_索引(){
arr[i]=&chr.to_string()。重复(3);
}
}

但是,我在借用时删除了错误
临时值
。这里有什么指示吗?

问题是
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
只保存引用,而其中的字符串必须在其他地方拥有。一个可能的修复方法是简单地泄漏在循环中创建的临时字符串

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\u string()
仅在for循环体中有效。分配它会导致错误

您可以使用
Vec
而不是
Vec
来避免此问题


在这里,我们看到字符串
“\u.”到\u String()
被复制了五次(这不是很有效)。我怀疑您的真实代码并非如此。

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

您可以使用
Vec
而不是
Vec
来避免此问题

在这里,我们看到字符串
“\u.”到\u String()
被复制了五次(这不是很有效)。我怀疑您的真实代码并非如此。

使用字符串也可以尝试一行:

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

使用字符串也可以尝试一行:

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


正如其他人提到的,您正在创建的
字符串必须由某人拥有,否则它们最终会被删除。当编译器检测到在数组仍保留对它们的引用时发生此删除时,它将发出抱怨

你需要考虑谁需要拥有这些价值观。如果你的最终阵列是它们生存的自然场所,只需将它们移动到那里:

fn main(){
设mut arr=Vec::具有_容量(5);
对于“abcde”中的(i,chr)。char_索引(){
arr.push(chr.to_string()。重复(3));
}
}
如果您确实需要一个
&str
数组,您仍然需要将这些值保持为“活动”状态,至少只要引用本身:

fn i_only_consume_refs(数据:Vec)->({}
fn main(){
设mut arr=Vec::具有_容量(5);
对于“abcde”中的(i,chr)。char_索引(){
arr.push(chr.to_string()。重复(3));
}
设refs=arr.iter().collect();
仅限i_消费参考(参考)
}
在这里,我们仍然将所有创建的
字符串
移动到向量
arr
,然后对其元素进行引用。这样,只要
arr
(拥有字符串的人)是有效的,引用向量就是有效的


TL;DR:当你保留对它们的引用时,需要有人拥有这些
String
s。您不能创建临时字符串,而只能存储引用,否则您将拥有对已删除值的引用,这确实非常糟糕,编译器不会允许您这样做。

正如其他人所提到的,您正在创建的
字符串必须由某个人拥有,否则它们最终将被删除。当编译器检测到在数组仍保留对它们的引用时发生此删除时,它将发出抱怨

你需要考虑谁需要拥有这些价值观。如果你的最终阵列是它们生存的自然场所,只需将它们移动到那里:

fn main(){
设mut arr=Vec::具有_容量(5);
对于“abcde”中的(i,chr)。char_索引(){
arr.push(chr.to_string()。重复(3));
}
}
如果您确实需要一个
&str
数组,您仍然需要将这些值保持为“活动”状态,至少只要引用本身:

fn i_only_consume_refs(数据:Vec)->({}
fn main(){
设mut arr=Vec::具有_容量(5);
对于“abcde”中的(i,chr)。char_索引(){
arr.push(chr.to_string()。重复(3));
}
设refs=arr.iter().collect();
仅限i_消费参考(参考)
}
在这里,我们仍然将所有创建的
字符串
移动到向量
arr
,然后对其元素进行引用。这样,只要
arr
(拥有字符串的人)是有效的,引用向量就是有效的


TL;DR:当你保留对它们的引用时,需要有人拥有这些
String
s。您不能创建临时字符串,只能存储引用,否则您将有一个对已删除值的引用,这确实非常糟糕,编译器不会允许您这样做。

泄漏意味着引用的
以后将永远不会从内存中删除。泄漏意味着引用的
以后将永远不会从内存中删除。虽然这解决了OP的问题,需要注意的是,@wasmup的答案使用更惯用的Rust产生相同的结果。虽然这解决了OP的问题,但需要注意的是,@wasmup的答案使用更惯用的Rust产生相同的结果