如何在单个rust函数中接受str,String和&String

Rin*_*ese 5 rust borrowing

我想编写一个函数,该函数接受“ str”,“ String”和借用的“&String”。
我编写了以下2个函数:

fn accept_str_and_ref_string(value: &str)
{
    println!("value: {}", value);
}

fn accept_str_and_string<S: Into<String>>(value: S)
{
    let string_value: String = value.into();
    println!("string_value: {}", string_value);
}

fn main() {
    let str_foo = "foo";
    let string_foo = String::from("foo");

    accept_str_and_ref_string(str_foo);
    accept_str_and_ref_string(&string_foo);

    accept_str_and_string(str_foo);
    accept_str_and_string(string_foo);
}
Run Code Online (Sandbox Code Playgroud)

但我想要1功能,所以我可以做到这一点:

accept_all_strings(str_foo);
accept_all_strings(&string_foo);
accept_all_strings(string_foo);
Run Code Online (Sandbox Code Playgroud)

这可能吗?

Kap*_*lan 14

自 2015 rust 版本以来,该accept_all_strings功能按照 OP 的要求运行Into<String>特征:

\n
fn accept_all_strings<S: Into<String>>(value: S) {\n    let string_value = value.into();\n    println!("string_value: {string_value}");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

谢杰里米·乔恩的提示。函数签名现在可以这样缩短:

\n
fn accept_all_strings(value: impl Into<String>) {\n    let string_value = value.into();\n    println!("string_value: {string_value}");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

操场

\n

String关于、 、&str之间的转换的非常好的概述Vec<u8>可以在这里&[u8]找到\xe2\x80\xa6

\n


Frx*_*rem 7

您可以使用AsRef<str>特征:

// will accept any object that implements AsRef<str>
fn print<S: AsRef<str>>(stringlike: S) {
    // call as_ref() to get a &str
    let str_ref = stringlike.as_ref();

    println!("got: {:?}", str_ref)
}

fn main() {
    let a: &str = "str";
    let b: String = String::from("String");
    let c: &String = &b;

    print(a);
    print(c);
    print(b);
}
Run Code Online (Sandbox Code Playgroud)

print功能将支持的任何类型的工具AsRef<str>,它包括&strString&String

  • @malthe我个人通常只使用“stringlike.as_ref().to_string()”,因为我喜欢拥有相同的签名,无论我是否需要自有或借用的字符串。我认为对于已经拥有字符串的参数来说这可能有点低效,所以如果你想避免这种情况,你可以使用其他特征,比如“S: Into&lt;String&gt;”。 (4认同)