rust str 从字符串中切片

A B*_*ton 6 string match slice rust

“切片是一种引用,因此它没有所有权。”

以下代码经过简化。它需要使用 a 返回一个切片match。除了一个匹配臂之外,所有匹配臂都返回一个字符串切片。一只手臂需要在切片周围添加单引号,因此我们转向使用format!return String。然后该字符串必须转换为&str.

该错误表明生成的切片被匹配臂中的临时字符串引用。

11 |     ret
   |     ^^^ returns a value referencing data owned by the current function
Run Code Online (Sandbox Code Playgroud)

简化后的代码如下。请注意,我们没有使用文字,而是&str从第三方板条箱返回的文字。

fn my_func(input: &str) ->&str {
    
    let ret =
        match input {
            "a" => "Apha", // in fact, a &str from a crate
            _ => format!("'{}'", "Quoted" ).as_str(), 
        };
        
    ret
}
 
Run Code Online (Sandbox Code Playgroud)

&str是需要的,因为&str然后使用 推送push_str()

fn main() {
    let mut s = String::new();
    s.push_str(my_func("a"));
    
...
Run Code Online (Sandbox Code Playgroud)

对于在匹配中复制 str 或取消引用临时字符串,您有何建议?

Joh*_*ica 6

您无法返回对本地分配的引用,String因为函数返回时该字符串将被删除。没有办法绕过这个问题。A&str只是与您想要返回的数据类型不匹配。

最直接的解决方法是返回一个拥有的String.

fn my_func(input: &str) -> String {
    match input {
        "a" => "Alpha".to_string(),
        _ => format!("'{}'", "Quoted" ), 
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是返回 a Cow<'_, str>,它可以保存借用的或拥有的字符串,具体取决于您拥有的字符串。这有点麻烦,但确实避免了不必要的分配。我仅在效率至关重要的情况下才推荐这样做;否则,就返回String

fn my_func(input: &str) -> Cow<'_, str> {
    match input {
        "a" => "Alpha".into(),
        _ => format!("'{}'", "Quoted" ).into(), 
    }
}
Run Code Online (Sandbox Code Playgroud)

我还将提到第三个选项——用于教育目的,而不是实际使用,因为它会泄漏内存。'static如果泄漏某个拥有的对象,您可以获得该对象的引用。泄漏的内存对于程序的其余部分有效,因为它从未被释放,因此您实际上可以获得对它的引用。

// Warning: Do not use! Leaks memory.
fn my_func(input: &str) -> &'static str {
    match input {
        "a" => "Alpha",
        _ => Box::leak(format!("'{}'", "Quoted").into_boxed_str()), 
    }
}
Run Code Online (Sandbox Code Playgroud)