字符串
Rust 字符串的分多种:
- 语言级别
str
,通常以引用类型出现 &str
, 不 具备所有权,且 不 可变(无法被修改);
- 标准库的实现,如:
- 使用最广泛的
String
,具有所有权、且 可变;
- 还有
OsString
、OsStr
、CsString
、CsStr
这些。
字符串字面量是切片引用。
也就是说:
| let s1 = "Hello, Boii!"; // s1 类型为 &str
|
等价于:
| let s1: &str = "Hello, Boii!";
|
Rust 中字符是 Unicode 编码,每个字符固定占 4 个字节。但是字符串是 UTF-8 编码,这是一种变长编码,字符串的每个字符所占字节数在 1~4 字节之间。
String 与 str 转换
-
String 转 str,取引用即可
| fn main() {
let s: String = String::from("Hello, Boii");
let s1: &str = &s; // 第一种方式
let s2: &str = &s[..]; // 第二种方式
let s3: &str = s.as_str(); // 第三种方式
}
|
这种灵活的用法是因为 Deref
这个 trait 隐式强制转换了。
-
str 转 String
| fn main() {
let s1: String = "Hello, Boii".to_string(); // 第一种方式
let s2: String = String::from("Hello, Boii"); // 第二种方式
}
|
字符串操作
追加 push、push_str
- 在原有字符串上追加,要求 可变,所以字符串变量需加
mut
关键字。
| let mut s = String::from("Hello, Boii");
s.push('!');
println!("追加字符 push() -> {}", s);
s.push_str(" and Eva");
println!("追加字符串 push_str() -> {}", s);
|
Output:
| 追加字符 push() -> Hello, Boii!
追加字符串 push_str() -> Hello, Boii! and Eva
|
插入 insert、insert_str
- 在原有字符串上追加,要求 可变,所以字符串变量需加
mut
关键字。
| let mut s = String::from("Hello, Boii");
s.insert(5, '~');
println!("插入字符 insert() -> {}", s);
s.insert_str(8, " Mr. ");
println!("插入字符串 insert_str() -> {}", s);
|
Output:
| 插入字符 insert() -> Hello~, Boii
插入字符串 insert_str() -> Hello~, Mr. Boii
|
替换 replace、replacen、replace_range
-
replace(old, new),
- 该方法会替换 所有 匹配到的字符串;
- 返回 新字符串, 不 要求可变。
| let s = String::from("I like rust. rust is the best language.");
let s1 = s.replace("rust", "RUST")
dbg!(s1);
|
Output:
| s1 = "I like RUST. RUST is the best language."
|
-
replacen(old, new, num)
- 该方法会替换 前 num 个 匹配到的字符串;
- 返回 新字符串, 不 要求可变。
| let s = String::from("I like rust. rust is the best language.");
let s1 = s.replace("rust", "RUST", 1)
dbg!(s1);
|
Output:
| s1 = "I like RUST. rust is the best language."
|
-
replace_range(range, new)
- 该方法会将指定的范围内的字符替换成新字符串;
- 在 原有字符串 上修改,要求可变,所以字符串变量需加
mut
关键字。
| let mut s = String::from("I like rust. rust is the best language.");
s.replace_range(7..11, "Golang");
dbg!(&s);
s.replace_range(7.., "Rust");
dbg!(&s);
|
Output:
| &s = "I like Golang. rust is the best language."
&s = "I like Rust"
|
删除 pop、delete、truncate、clear
-
pop()
- 删除 并 返回 被删除的字符;
- 在 原有字符串 上修改,要求可变,所以字符串变量需加
mut
关键字;
- 因为有返回值,为 Option 类型,如果字符串为空则返回 None。
| let mut s = String::from("Rust pop 中文!");
let p1 = s.pop();
let p2 = s.pop();
dbg!(p1);
dbg!(p2);
dbg!(s);
|
Output:
| p1 = Some(
'!',
)
p2 = Some(
'文',
)
s = "Rust pop 中"
|
-
remove(index)
- 删除 并 返回字符串的 被删除的字符;
- 在 原有字符串 上修改,要求可变,所以字符串变量需加
mut
关键字;
- 因为有返回值,为 char 类型;如果字符串为空串,调用 remove 会发生运行时错误。
- 如果 index 不是合法的字符边界,会发生错误。
| let mut s = String::from("测试一下 remove 方法");
let p1 = s.remove(0);
// let p2 = s.remove(1); // 测是中文,占 3 个字节 0, 1, 2, 所以 1 不是合法的字符边界,这里会报错
let p3 = s.remove(3);
dbg!(p1);
dbg!(p3);
dbg!(s);
|
Output:
| p1 = '测'
p3 = '一'
s = "试下 remove 方法"
|
-
truncate(index)
- 删除字符串中 从指定位置开始到结尾的全部字符;
- 在 原有字符串 上修改,要求可变,所以字符串变量需加
mut
关键字;
- 没有返回值;如果字符串为空串,也不会发生错误。
- 如果 index 不是合法的字符边界,会发生错误。
| let mut s = String::from("测试 truncate");
s.truncate(3);
dbg!(s);
|
Output:
-
clear()
- 清空字符串;
- 在 原有字符串 上修改,要求可变,所以字符串变量需加
mut
关键字;
- 相当于
truncate(0)
.
| let s = String::from("clear string");
s.clear();
dbg!(s);
|
Output:
连接字符串
-
使用 +
或 +=
连接
使用 +
操作符时相当于调用 std::string
标准库中的 add()
方法,所以要求第二个参数(即 +
操作符右边的变量)为 &str 类型。
不过 +
和 +=
都是返回一个 新字符串。
| let s1 = String::from("Hello");
let s2 = String::from("World!");
let s3 = s1 + &s2;
let mut s4 = s3 + "!";
s4 += "~~~";
println!("{}", s4);
|
Output:
2. 使用 format!()
连接
format!()
方式适用于 String
和 &str
,用法与 println!()
类似。
| let s1 = String::from("Hello");
let s2 = "Boii!";
let s = format!("{} {}", s1, s2);
println!("{}", s);
|
Output:
字符串转义
Rust 可以用过转义的方式 \
输出 ASCII 和 Unicode 字符。
也可以取消转义,原样打印出来
操作 UTF-8 字符串