传递"&str"对 Rust 的性能不是不好吗?



一般建议在Rust中接受&str而不是String

假设我有几个函数和一个String实例:

use std::collections::HashMap;
fn do_something_str(string: &str) {
let mut map = HashMap::new();
map.insert(string.to_owned() /* copying (expensive)? */, "value");
}
fn do_something_string(string: String) {
let mut map = HashMap::new();
map.insert(string /* moving (cheap)? */, "value");
}
fn main() {
let string = String::from("123");
do_something_str(&string);
do_something_string(string);
}

游乐场

复制是否发生在do_something_str()意味着它将更慢/更高的临时内存消耗?

p。我知道我不需要显式地调用.to_owned(),下面也可以工作:

fn do_something_str(string: &str) {
let mut map = HashMap::new();
map.insert(string /* copying (expensive)? */, "value");
}

但是由于hashmap拥有键,我相信它会隐式克隆它。如果我说错了,请纠正我。

一般建议在Rust中接受&str而不是String

不完全是。一般的智慧是接受&str而不是&String。也就是说,当您已经打算对引用进行操作时,更通用的类型被认为是更好的。

如果您需要一个拥有的String,实际上传递一个引用只是为了立即克隆它是浪费的。首先接受String将选择权留给了调用者:如果他们需要为自己保留字符串的副本,他们可以使用clone()。否则,调用者只将String移动到HashMap中,不涉及克隆。

但是由于hashmap拥有键,我相信它会隐式克隆它。如果我说错了,请纠正我。

HashMap在插入时不克隆。这将需要Clone性状绑定在HashMap上。

HashMap<&str, T>仍然会"own"密钥,但在这种情况下,密钥是&str,而不是它自己的对等物(String)。当然,这将防止HashMap比键引用的字符串更长寿。以下示例未通过借用检查:

use std::collections::HashMap;
fn main() {
let mut map: HashMap<&str, ()> = HashMap::new();
{
let key = String::from("foo");
map.insert(&key, ()); // error[E0597]: `key` does not live long enough
}
println!("{:?}", map.get("foo"));
}

&str上调用.to_owned()确实会创建一个字符串的私有副本,并与相应的性能/内存相关联。

正如您正确指出的,您还可以有一个HashMap<&str, V>,即HashMap,其密钥类型为&str。这并不需要克隆字符串。然而,这意味着HashMap的生存期受到&str的生存期的限制。

最新更新