Rust
中字符串和 Java
和 Go
中的表示有很大的区别,刚开始接触的时候有点儿懵,今天花点时间总结备忘一下。
Rust
字符串有两种形式:str
和 String
,str
是内置的原始数据类型,通常是以借用的形式(&str
字符串 slice
)使用,而 String
是标准库提供的一种结构体,内部存储一个 u8
类型的 Vec
:
1 | pub struct String { |
2 | vec: Vec<u8>, |
3 | } |
str
1 | let s = "hello world!"; |
2 | |
3 | // let s: &'static str = "hello world!"; |
s
变量是一个 &str
类型,不可变的字符串,也可称为字面量,文本被直接储存在程序的二进制文件中,拥有固态生命周期('static
),是 let s: &'static str = "hello world!";
的简写定义方式。
String
1 | let mut s1 = String::new(); |
2 | // let mut s1 = String::from("hello world!"); |
3 | s1.push_str("hello world!"); |
4 | s1.push_str(" welcome."); |
5 | |
6 | println!("{}", s1); |
7 | // Output: |
8 | // hello world! welcome. |
String
是可变的、有所有权的、堆上分配的 UTF-8
的字节缓冲区。
相互转换
- &str -> String
1 | let s = "hello world!"; // variable s: &str |
2 | |
3 | let s1 = String::from(s); // variable s1: String |
4 | let s1 = s.to_string(); |
5 | let s1 = s.to_owned(); |
- String -> &str
1 | let s = String::from("hello world!"); // variable s: String |
2 | let s1 = s.as_str(); // variable s1: &str |
3 | let s1 = &s[..]; // 相当于:&s[0..s.len()]; |
&String
可以当做是 &str
,例如:
1 | fn main() { |
2 | let s = String::from("hello world!"); |
3 | foo(&s); |
4 | } |
5 | fn foo(s: &str) { |
6 | println!("{}", s); |
7 | } |
+ 号运算
字符串 +
号运算是 String
的一个内联函数,定义如下:
1 | impl Add<&str> for String { |
2 | type Output = String; |
3 | |
4 | |
5 | fn add(mut self, other: &str) -> String { |
6 | self.push_str(other); |
7 | self |
8 | } |
9 | } |
所以两个字面量字符串(&str
)不能使用 +
,例如:"hello " + "world";
会报错误: '+' cannot be used to concatenate two '&str' strings
。
根据 +
的定义,一个可变的 String
字符串进行 +
后会失去所有权,例如:
1 | let mut s = String::from("hello world!"); |
2 | let s1 = s + " welcome."; |
3 | |
4 | // println!("{}, {}", s, s1); |
5 | // ^ value borrowed here after move |
以上代码会出现以下警告:
1 | // | |
2 | // | let mut s = String::from("hello world!"); |
3 | // | ----^ |
4 | // | | |
5 | // | help: remove this `mut` |
6 | // | |
7 | // = note: #[warn(unused_mut)] on by default |
查阅说是有 #[warn(unused_mut)]
注解后 variable does not need to be mutable。去掉以上代码中 String
定义时候用以标识可变的 mut
关键字就可以了。不太明白为啥可以这样,待日后详查。