Post

04所有权·3Slice 类型

介绍rust的一个特性:所有权之Slice 类型

定义[20230105]:

提供一种不持有所有权的数据类型。(本质还是指针。使用方式跟python的切片类似)

字符串 slice(&str)

(一).字符串切片是指向字符串中一部分内容的引用

1
2
3
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];

04-09

(二).语法形式

  • [start..end]
  • 语法糖
    • (1).[0..end] => [...end]
    • (2).[satrt..s.len] => [...end]
    • (3).[0..s.len] => [...]

(三).注意事项

  • 1.字符串切片的索引范围必须发生在有效的UTF-8字符边界内
  • 2.如果尝试从一个多字节字符的中间位置创建字符串 slice,程序将会因错误而退出

(四).字符串字面值就是slice

  • 字符串字面值被直接存储在二进制程序中.rust let s = "Hello, world!";
  • &str 是一个不可变引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}
fn main() {
    let mut s = String::from("hello world");
    let word = first_word(&s);
    s.clear(); //error[E0502]: cannot borrow `s` as mutable because
                //it is also borrowed as immutable(&str 是不可变的)
    println!("the first word is: {}", word);
}
  • 将字符串切片作为参数传递更具通用性.(String和&str都可以作为形参传递)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main() {
    let my_string = String::from("hello world");

    //`first_word` 适用于 `String`(的 slice),部分或全部
    let word = first_word(&my_string[0..6]);

    //`first_word` 也适用于 `String` 的引用,
    //  这等价于整个 `String` 的 slice
    let word = first_word(&my_string);

    //因为字符串字面值已经 **是** 字符串 slice 了,
    //  这也是适用的,无需 slice 语法!
    let word = first_word(my_string_literal);
}
This post is licensed under CC BY 4.0 by the author.