&str 和 &String 有什么区别

way*_*yne 2 rust

我正在浏览Microsoft 的 Rust 教程,内容是

\n
\n

实现该copy_and_return函数,以便它返回\n对插入到向量中的值的引用

\n
\n

这里给出了解决方案,但它与我的不同,它使用 &String 作为返回类型,而我使用 &str。

\n
// standard solution\nfn copy_and_return<\'a>(vector: &\'a mut Vec<String>, value: &\'a str) -> &\'a String {\n    vector.push(String::from(value));\n    vector.get(vector.len() - 1).unwrap()\n}\n
Run Code Online (Sandbox Code Playgroud)\n
// my solution\nfn copy_and_return<\'a>(vector: &\'a mut Vec<String>, value: &\'a str) -> &\'a str {\n    vector.push(String::from(value));\n    return value; // simply return value\n}\n\nfn main() {\n    let name1 = "Joe";\n    let name2 = "Chris";\n    let name3 = "Anne";\n\n    let mut names = Vec::new();\n\n    assert_eq!("Joe", copy_and_return(&mut names, &name1));\n    assert_eq!("Chris", copy_and_return(&mut names, &name2));\n    assert_eq!("Anne", copy_and_return(&mut names, &name3));\n\n    assert_eq!(\n        names,\n        vec!["Joe".to_string(), "Chris".to_string(), "Anne".to_string()]\n    )\n}\n
Run Code Online (Sandbox Code Playgroud)\n

除了返回类型之外,我和标准方案的另一个区别是我只是简单地返回了参数value,而标准方案则采用了复杂的方式vector.get(vector.len() - 1).unwrap()

\n

我想知道我的解决方案是否有问题,教程采用了另一种方式?

\n
\n

虽然 @Masklinn 为我的问题提供了一个很好的答案,但它有点特定于我给出的示例,但没有直接解决标题What is the difference between &str and &String
\n我发现这个讨论内容非常丰富:

\n
\n

基本上,aString包装并管理动态分配的 str 作为后备存储。\n由于 str 无法调整大小,因此 String 将动态分配/释放内存。\n&str因此,A 是直接对 String 后备存储的引用,而 &String 是对\xe2\x80\x9cwrapper\xe2\x80\x9d 对象。\n此外,&str 可用于子字符串,即它们是切片。&String 始终引用整个字符串。

\n
\n

Rust 书的4.3 章也有帮助

\n

Mas*_*inn 6

我想知道我的解决方案是否有问题,教程采用了另一种方式?

我不认为本身有什么问题,你的函数甚至可能更好地匹配函数名称,具体取决于它的解释方式:你应该复制并返回原始文件,还是复制并返回副本?你的是第一选择,他们的是第二选择。

它与生命周期无关,但这确实对程序行为产生了影响:在“官方”解决方案中,结果是对插入到 中的值的引用Vec,这意味着只要向量存在,它就会“存活” (至少假设向量没有被修改)。

value: &'a str如果您替换为value: &'_ str(又名“您不关心但与 不同的一生”),您可以看到差异'a:官方解决方案仍然可以编译,而您的则不能。

但请注意,无论如何,官员也可以返回&'a str

fn copy_and_return<'a>(vector: &'a mut Vec<String>, value: &'_ str) -> &'a str {
    vector.push(String::from(value));
    vector.get(vector.len() - 1).unwrap()
}
Run Code Online (Sandbox Code Playgroud)

官方解决方案很难通过例如

vector.get(vector.len() - 1)
Run Code Online (Sandbox Code Playgroud)

是一种复杂的写作方式

vector.last()
Run Code Online (Sandbox Code Playgroud)

但我不能说,他们可能只是不想用高级 API 之类的东西让读者不知所措。