通用集合类型-字符串 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用于追加单个字符chars.push('!');println!("{}", s); // hello world!
复制代码
为什么字符串切片是以引用的方式出现?为了方便再次使用:
let mut s = String::from("hello");
// s2的类型是&strlet 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和s3println!("{}", s2); // , worldprintln!("{}", s3); // !
// 由于上面字符串拼接过程中开头的s是具有所有权的字符串,// 拼接之后所有权转移给了s4println!("{}", 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); // helloprintln!("{}", s2); // , worldprintln!("{}", s3); // !
复制代码
字符串索引
在 JS 中,可以使用索引来访问字符串,但是在 rust 中是不支持的:
let s = "hello";let h = s[0]; // 报错,字符串不支持索引
// 因为有些字符的Unicode标量值占用两个字符,// 当我们按照索引访问时,可能访问了字符的一半,// 不是一个合法字符,所以rust不允许这么做let s2 = "🍔";let s3 = "a";println!("{}", s2.len()); // 4println!("{}", 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}
复制代码
评论