Rust和借用中的字符串连接
我最近一直在学习 Rust。
我偶然发现了一个真正让我烦恼的片段。
为什么这样做
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2;
println!("{}",s3)
}
而这不?
fn main() {
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = &s1 + s2;
println!("{}",s3)
}
先感谢您
回答
从技术角度来看,这是因为String实现Add<&str>和Deref<Target=str>. 因此,编译器可以将您的第一个示例 , 重写s1 + &s2为s1.add (s2.deref()).
但是既不是&String也不是&str实现Add,所以编译器不能重&s1 + …写成(&s1).add (…).
从语言设计的角度来看,之所以做出这个选择,是因为s1 + …如果在 的当前内容之后已经分配了足够的空间,则可以不分配s1,但&s1 + …总是需要分配,因此决定明确分配。如果您想s1在操作后继续使用原件,您需要明确地克隆它:
let s3 = s1.clone() + &s2;
或者如果性能真的那么重要,您需要预先分配足够的内存来保存结果:
let s3 = String::with_capacity (s1.len() + s2.len()) + &s1 + &s2;