之前我们已经使用过 String,对于 String 的解释是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型。String 的数据是存在于堆上的。下面再看一些关于 String 的使用。

1. 创建字符串

1
2
3
4
5
6
7
8
fn main() {
// 创建一个字符串
let mut s1 = String::new();
s1.push_str("Hello");

let mut s2 = String::from("Hello");
let mut s3 = "Hello".to_string();
}

上面 s1,s2,s3分别创建了一个字符串,并填充内容 “Hello”,这三种方式都可以达到相同的目的。

2. 除上可以 push_str ,还可以 push 单个字符

1
2
3
4
5
6
7
8
fn main() {
let mut s1 = String::new();
s1.push('H');
s1.push('e');
s1.push('l');
s1.push('l');
s1.push('o');
}

3.字符串的拼接

1
2
3
4
5
6
7
fn main() {
let s1 = "Hello".to_string();
let s2 = ", Rust".to_string();
let s3 = " Haha".to_string();
let s4 = s1 + &s2 + &s3;
println!("s2: {}\ns3: {}\ns4: {}", s2, s3, s4);
}

注意,如果要使用 + 去拼接字符串,会先获得第一个变量的所有权,然后附加上后面变量的内容拷贝。上面的代码,s4 创建后,s1将不再有效。

4. 使用 format! 宏拼接字符串

在涉及到很多的字符串要拼接时,使用 + 就不那么方便,下面使用 format! 宏进行操作,就方便很多。

1
2
3
4
5
6
7
fn main() {
let s1 = "Hello".to_string();
let s2 = ", Rust".to_string();
let s3 = " Haha".to_string();
let s4 = format!("{}-{}-{}", s1, s2, s3);
println!("s1: {}\ns2: {}\ns3: {}\ns4: {}", s1, s2, s3, s4);
}

从上面可以看出,format! 宏在拼接字符串时,并不获取任何所有权

5. 获取字符串的长度

1
2
3
4
fn main() {
let s1 = "Hello".to_string();
let len = s1.len();
}

6. 字符串的遍历

1
2
3
4
5
6
fn main() {
let s1 = "Hello".to_string();
for char in s1.chars(){
println!("{}", char);
}
}

String 不支持以 [0] 这样的索引形式访问单个字符,具体原因请看后面关于 String 的详细内容连接。但是 String 可以用上面的形式遍历每一个字符。

7. 字符串原始字节遍历

1
2
3
4
5
fn main() {
for b in "नमस्ते".bytes() {
println!("{}", b);
}
}

上面只是讨论 String 很基本的使用,但是 String 并不简单,里面还有很多很多内容,具体到里面的一些原理和实现,请阅读下面的连接

Rust 程序语言设计 https://kaisery.github.io/trpl-zh-cn/ch08-02-strings.html

String 官方文档 https://doc.rust-lang.org/std/string/struct.String.html