我希望将使用String
宏创建的format!
转换为&str
并使用let
绑定将其分配给一个值:
fn main() {
let my_bool = true;
let other = String::from("my_string");
let result = if my_bool {
format!("_{}", other).as_str()
} else {
"other"
};
println!("{}", result);
}
执行此操作时,编译器抱怨临时String
值在语句末尾释放(根据我的理解),这意味着我无法动态创建{{1 }}:
&str
我一直在试图了解Rust的生命周期系统,但是我无法真正围绕这个系统。 Rust提出以下建议:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:5:9
|
4 | let result = if my_bool {
| ------ borrow later stored here
5 | format!("_{}", other).as_str()
| ^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
6 | } else {
| - temporary value is freed at the end of this statement
|
我将 = note: consider using a `let` binding to create a longer lived value
包裹在format!("_{}", other)
装订中:
let
但是它似乎无法解决问题,因为当我在此绑定上调用fn main() {
let my_bool = true;
let other = String::from("my_string");
let result = if my_bool {
let s = format!("_{}", other);
s.as_str()
} else {
"other"
};
println!("{}", result);
}
时,它仍然抱怨借入的值寿命不足:
as_str()
当我省略整个error[E0597]: `s` does not live long enough
--> src/main.rs:6:9
|
4 | let result = if my_bool {
| ------ borrow later stored here
5 | let s = format!("_{}", other);
6 | s.as_str()
| ^ borrowed value does not live long enough
7 | } else {
| - `s` dropped here while still borrowed
时,此方法有效,但我宁愿不这样做,因为这会在原始代码库中引起很多麻烦。
此外,这似乎有点不合时宜,因为那时我仍然不知道为什么会失败。
我将如何系统地解决此问题?
答案 0 :(得分:4)
&str
是一个借入的字符串,因此您不能从临时String
中获得一个字符串,否则引用将超出其绑定的值。
但是,您可以使用Cow
类型来执行您想要的操作:
use std::borrow::Cow;
fn main() {
let my_bool = true;
let other = String::from("my_string");
let result = if my_bool {
Cow::Owned(format!("_{}", other))
} else {
Cow::Borrowed("other")
};
assert_eq!("_my_string", result);
}
Cow
(对于写入时克隆)是一个enum
,它拥有或借用数据。在这种情况下,result
的类型为Cow<str>
。
您可以通过编写以下代码来简化表示法:
let result = if my_bool {
format!("_{}", other).into()
} else {
Cow::Borrowed("other")
};
或(样式):
let result: Cow<str> = if my_bool {
format!("_{}", other).into()
} else {
"other".into()
};