字符串在 Rust 不像其他语言那么简单,先来看看 切片
切片
和 go 一样;切片允许你引用集合中部分连续的元素序列,而不是引用整个集合。
对于字符串而言,切片就是对 String 类型中某一部分的引用
fn main() {
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
}
hello 和 world 引用了 s 的一部分内容,通过[0..5]
来指定;
括号包括的一个序列:[开始索引…终止索引];
右半开区间
在切片数据结构内部会保存开始的位置和切片的长度,其中长度是通过 终止索引 - 开始索引 的方式计算得来的
// 从索引 0 开始 可以省略 0,以下等效
let slice = &s[0..2];
let slice = &s[..2];
// 最后一个字节,也可以这样使用
len = s.len();
let slice = &s[4..len];
let slice = &s[4..];
中文
中文在 UTF-8 中占用三个字节,所以使用切片时要小心,如果取在中间,代码会崩溃
如:
let s = "中国人";
let a = &s[0..2];
println!("{}",a);
如果提取第一个汉字,则需要 &s[0..3]
字符串切片的类型标识是 &str
其他切片
因为切片是对集合的部分引用,因此不仅仅字符串有切片,其它集合类型也有,例如数组:
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];
assert_eq!(slice, &[2, 3]);
该数组切片的类型是 &[i32],数组切片和字符串切片的工作方式是一样的,例如持有一个引用指向原始数组的某个元素和长度。
字符串字面量是切片
// 字符串字面值
let s = "Hello, world!";
以下亦可
let s: &str = "Hello, world!";
该切片指向了程序可执行文件中的某个点,这也是为什么字符串字面量是不可变的,因为 &str 是一个不可变引用。