Rust 中的字符串连接和借用
String concatenation in rust and borrowing
最近在学习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>
and Deref<Target=str>
。因此编译器可以将您的第一个示例 s1 + &s2
重写为 s1.add (s2.deref())
.
但是&String
和&str
都没有实现Add
,所以编译器无法将&s1 + …
改写成(&s1).add (…)
。
从语言设计的角度来看,做出此选择是因为如果在 s1
的当前内容之后已经分配了足够的 space,则 s1 + …
可以在没有分配的情况下完成,但是 &s1 + …
总是需要分配,因此决定明确分配。如果你想在操作后继续使用原来的s1
,你需要明确地克隆它:
let s3 = s1.clone() + &s2;
或者如果性能真的那么重要,您需要预分配足够的内存来保存结果:
let s3 = String::with_capacity (s1.len() + s2.len()) + &s1 + &s2;
最近在学习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>
and Deref<Target=str>
。因此编译器可以将您的第一个示例 s1 + &s2
重写为 s1.add (s2.deref())
.
但是&String
和&str
都没有实现Add
,所以编译器无法将&s1 + …
改写成(&s1).add (…)
。
从语言设计的角度来看,做出此选择是因为如果在 s1
的当前内容之后已经分配了足够的 space,则 s1 + …
可以在没有分配的情况下完成,但是 &s1 + …
总是需要分配,因此决定明确分配。如果你想在操作后继续使用原来的s1
,你需要明确地克隆它:
let s3 = s1.clone() + &s2;
或者如果性能真的那么重要,您需要预分配足够的内存来保存结果:
let s3 = String::with_capacity (s1.len() + s2.len()) + &s1 + &s2;