通用集合类型-字符串 String
本节介绍之前就认识的一个数据集合:String,也就是就是字符 char 的集合,rust 在语言核心部分只有一种字符串类型,那就是字符串切片 str,它通常以借用的形式出现,也就是 &str。当我们提到“字符串”时,他们通常指的是 String 和字符串切片 &str 这两种类型。另外,字符串都是基于 UTF-8 编码的。
创建一个字符串
许多对于 Vec<T>可用的操作也同样可用于 String,我们可以从 new 函数开始来创建一个字符串:
// 创建一个空字符串
let s = String::new()
// 使用字面量&str切片转换成字符串类型
let s2 = "hello".to_string()
// 还可以使用from方法:
let s3 = String::from("hello")
复制代码
更新字符串
使用 push_str 或 push 向字符串中添加内容:
let mut s = String::from("hello");
// push_str用于追加字符串
s.push_str(" world");
println!("{}", s); // hello world
// push用于追加单个字符char
s.push('!');
println!("{}", s); // hello world!
复制代码
为什么字符串切片是以引用的方式出现?为了方便再次使用:
let mut s = String::from("hello");
// s2的类型是&str
let s2 = " world";
// 这里不会拿走s2的所有权,因为s2是引用类型
s.push_str(s2);
println!("{}", s);
// "hello, world"
// 如果s2的类型不是引用形式,
// s.push_str(s2)将拿走s2的所有权
// s2将不能再被使用
println!("{}", s2);
// " world"
复制代码
拼接字符串有一个限制,第一个字符串需要是 String 类型,后面的都是 &str 类型:
let s = String::from("hello");
let s2 = String::from(", world");
let s3 = "!";
// 以s开头,将字符串拼接
let s4 = s + &s2 + &s3;
// 获取拼接结果
println!("{}", s4); // "hello, world!"
// 获取被拼接的s2和s3
println!("{}", s2); // , world
println!("{}", s3); // !
// 由于上面字符串拼接过程中开头的s是具有所有权的字符串,
// 拼接之后所有权转移给了s4
println!("{}", s); // 报错,没有了所有权,不再可用
复制代码
字符串还可以使用 format!宏来拼接:
let s = String::from("hello");
let s2 = String::from(", world");
let s3 = "!";
// format!的用法类似于println!
// 这种方式不会获取任何一个字符串的所有权
let s4 = format!("{}{}{}",s, s2, s3);
// 所有字符串都可用
println!("{}", s4); // hello, world!
println!("{}", s); // hello
println!("{}", s2); // , world
println!("{}", s3); // !
复制代码
字符串索引
在 JS 中,可以使用索引来访问字符串,但是在 rust 中是不支持的:
let s = "hello";
let h = s[0]; // 报错,字符串不支持索引
// 因为有些字符的Unicode标量值占用两个字符,
// 当我们按照索引访问时,可能访问了字符的一半,
// 不是一个合法字符,所以rust不允许这么做
let s2 = "🍔";
let s3 = "a";
println!("{}", s2.len()); // 4
println!("{}", s3.len()); // 1
复制代码
字符串切片
通过切片实现类似索引的效果:
let s = "🍔";
let s2 = &s[0..1]; // 报错, 非法字符
let s3 = &s[0..4]; // 🍔
复制代码
遍历字符串
使用 chars 方法进行遍历,过程中 rust 可以按照 Unicode 识别完整的字符:
let s = "hello, world🍔";
for c in s.chars() {
println!("{}", c);
// 依次输出:hello, world🍔
}
复制代码
使用 bytes 方法可以依次返回每个原始字节:
let s22 = "🍔";
for b in s22.bytes() {
println!("{}", b);
// 依次输出:240 159 141 148
}
复制代码
评论