rust 初探 – 切片
切片
- rust 的另外一种不持有所有权的数据类型:切片(slice)
示例:
fn main() {
let mut s = String::from("hello world");
let world_index = first_world(&s);
s.clear();
//这里清空之后,因为 world_index 和字符串没有关联,导致实际失去了有效性
//需要保证 world_index 和字符串直接的关联,保证其有效性
println!("{}", world_index);
}
fn first_world(s: &String) -> usize {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return i;
}
}
s.len()
}
基于此,rust 中采用切片来进行相关处理,并保证其中的关联。
- 字符串切片是指向字符串中一部份内容的引用
fn main() {
let s = String::from("hello world");
let hello = &s[..5]; //&s[..0], 整个字符串的切片: &s[..]
let world = &s[6..11];//&s[6..s.len()]
println!("{}, {}", hello, world);
}
注意
- 字符串切片的范围索引必须发生在有效的UTF-8 字符边界内
- 如果尝试从一个多字节的字符中创建字符串切片,程序会报错并退出
字符串切片重写示例:
fn main() {
let mut s = String::from("hello world");
let world_index = first_world(&s);
s.clear();
println!("{}", world_index);
}
fn first_world(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[..i];
}
}
&s[..]
}
/*
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:18:5
|
16 | let world_index = first_world(&s);
| -- immutable borrow occurs here
17 |
18 | s.clear();
| ^^^^^^^^^ mutable borrow occurs here
19 | println!("{}", world_index);
| ----------- immutable borrow later used here
*/
相关知识点
- 字符串字面值是被直接存储在二进制程序中
- let s = “hello”;
- 变量 s 的类型是 &str,它是一个指向二进制程序特定位置的切片,&str 是不可变的,所以字符串字面值也是不可变的
将字符串切片作为参数传递
- fn first_world(s: &String) -> &str {
- 最好是使用 &str 作为参数类型进行传递,因为这样函数既可以接收 String(使用切片) 和 &str 类型的参数了
fn main() {
let s = String::from("hello world");
let world_index = first_world(&s[..]);
println!("{}", world_index);
}
fn first_world(s: &str) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[..i];
}
}
&s[..]
}