双引号的意义是字面量,字面量的默认类型就是 &str。构造 String 的开销会违背 zero cost 原则。
str 不可以动态申请内存,而 + 需要。类似 c style char *。
零抽象原则下不会让字符串字面量动态申请内存。没有gc的语言都不会这样做。
Rust 有两类字符串,`String` 类型基于向量列表 `Vec
string s1 = "Hello,";
const string s2 = "world";
s1 += s2;
Rust 程序拼接字符串:
let mut s1 = "Hello,".to_string();
let s2 = "world".to_string();
s1 += &s2;
Rust 字符串的拼接,根本就是把加法操作符右侧的字符串,拷贝一份,并附到左侧字符串之后,同时右侧的字符串的所有权不受影响。Rust 语言的设计需要将「借用」显式写出,所以就比 C++ 多了一个借用操作符。两个 `&str` 也不能直接相加,但可以将 `&str` 加到 String 上,并且,两个 String 相加,要将 + 右侧的转换为借用形式:
let s = "Hello," + "world"; // Can't use + with two &str
let s = s1 + &s2; // Move s1 to s, and concats s2 to s
对于 + 右侧的 String 它必需转换成 `&str` 才能被连接到另一个字符串上,因为字符串对象没有 Copy 特性。更好的方式是使用 format! 宏:
let s1 = String::from("Hello");
let s2 = String::from("world.");
let s = format!("{}, {}", s1, s2);
format宏第一个参数只接受&str
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s = format!("{}-{}-{}", s1, s2, s3)
fn main(){
let mut s1 = String::from("hello ");
let s2 = String::from("world");
s1.push_str(s2.as_str());
println!("{}",s1);
}
拼接字符串有代价。
String要求一段连续的内存,而即将拼接的2个字符串在内存上必定不连续,这就意味着:
需要申请新空间
需要复制字符串
rust的设计就是在提醒你,拼接字符串的额外开销很大。