我有以下运行良好的代码:
fn main() {
let mut example = String::new();
if 1 + 1 == 2 {
example += &"string".to_string()
} else {
example += &'c'.to_string()
};
println!("{}", example);
}
当我将代码更改为此:
fn main() {
let mut example = String::new();
example += if 1 + 1 == 2 {
&"string".to_string()
} else {
&'c'.to_string()
};
println!("{}", example);
}
我收到以下错误:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:5:10
|
5 | &"string".to_string()
| ^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
6 | } else {
| - temporary value dropped here while still borrowed
7 | &'c'.to_string()
8 | };
| - temporary value needs to live until here
error[E0597]: borrowed value does not live long enough
--> src/main.rs:7:10
|
7 | &'c'.to_string()
| ^^^^^^^^^^^^^^^ temporary value does not live long enough
8 | };
| - temporary value dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
这对我来说毫无意义,因为两个代码片段看起来都是相同的。为什么第二个片段不起作用?
答案 0 :(得分:4)
您有already seen an explanation as to why this code cannot be compiled。这是一些有效且更接近您目标的代码:
hypothesis
我不会说这是惯用的Rust。我遇到的一件事是将example += &if 1 + 1 == 2 {
"string".to_string()
} else {
'c'.to_string()
};
不必要地分配到"string"
中。我将使用String::push_str
和String::push
编写这段代码:
String
如果您不附加字符串,我将直接对其进行评估:
if 1 + 1 == 2 {
example.push_str("string");
} else {
example.push('c');
}
我什至可以使用动态调度(尽管可能性较小):
let example = if 1 + 1 == 2 {
"string".to_string()
} else {
'c'.to_string()
};
或
let s: &std::fmt::Display = if 1 + 1 == 2 { &"string" } else { &'c' };
let example = s.to_string();
另请参阅:
答案 1 :(得分:3)
将&
应用于表达式时,Rust自动创建拥有该表达式求值结果的匿名变量。因此,您的代码大致相当于
fn main() {
let mut example = String::new();
example += if 1 + 1 == 2 {
let temp1 = "string".to_string();
&temp1
} else {
let temp2 = 'c'.to_string();
&temp2
};
println!("{}", example);
}
您现在希望可以清楚地看到,temp1
的范围(和生存期)仅限于true
表达式的if
分支,以及{ {1}}仅限于temp2
表达式的false
分支。范围/生存期均未扩展到if
表达式之外,因此if
的两个分支内的String
不能附加到if
。
相反,您的第一个示例大致等于
example
,并且在两种情况下,fn main() {
let mut example = String::new();
if 1 + 1 == 2 {
let temp1 = "string".to_string();
example += &temp1;
} else {
let temp2 = 'c'.to_string();
example += &temp2;
};
println!("{}", example);
}
和temp1
的寿命都足够长,因此可以复制temp2
的内容并将其附加到String
之前的example
和temp1
被删除。