如何将临时字符串转换为 &str?

Joë*_*ams 3 format lifetime rust

我希望将String使用format!宏创建的a转换为 a&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);
}
Run Code Online (Sandbox Code Playgroud)

锈游乐场

当我这样做时,编译器抱怨String在语句的末尾释放了临时值(根据我的理解),这意味着我无法动态创建&str

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);
}
Run Code Online (Sandbox Code Playgroud)

我一直试图了解 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
  |

Run Code Online (Sandbox Code Playgroud)

我包裹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);
}
Run Code Online (Sandbox Code Playgroud)

但它似乎并没有解决这个问题,因为当我调用as_str()这个绑定时,它仍然抱怨借来的价值活得不够长:

  = note: consider using a `let` binding to create a longer lived value
Run Code Online (Sandbox Code Playgroud)

当我省略整个 时if,这有效,但我宁愿不这样做,因为这会在原始代码库中引起很多麻烦。

此外,这似乎是一种逃避,因为那时我仍然不知道为什么会失败。

我将如何以系统的方式解决这个问题?

Fre*_*ios 8

&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);
}
Run Code Online (Sandbox Code Playgroud)

Cow(对于写入时的克隆)是enum拥有或借用数据的一个。在这种特殊情况下,result类型为Cow<str>

您可以通过编写来简化符号:

let result = if my_bool {
    format!("_{}", other).into()
} else {
    Cow::Borrowed("other")
};
Run Code Online (Sandbox Code Playgroud)

或(风格问题):

let result: Cow<str> = if my_bool {
    format!("_{}", other).into()
} else {
    "other".into()
};
Run Code Online (Sandbox Code Playgroud)