当前位置: 首页 > article >正文

Rust学习总结之所有权(三)

         slice是没有所有权的数据类型,slice 允许你引用集合中一段连续的元素序列,而不用引用整个集合。

一:字符串slice

fn main() {
    let s = String::from("hello world");

    let hello = &s[0..5];
    let world = &s[6..11];
    println!("{} {}",hello,world);
}

运行结果:

变量hello和world都是对s的数据部分进行部分引用,数据只有一份,如下图所示。

可以使用一个由中括号中的 [starting_index..ending_index] 指定的 range 创建一个 slice,其中 starting_index 是 slice 的第一个位置,ending_index 则是 slice 最后一个位置的后一个值。在其内部,slice 的数据结构存储了 slice 的开始位置和长度,长度对应于 ending_index 减去 starting_index 的值。所以对于 let world = &s[6..11]; 的情况,world 将是一个包含指向 s 索引 6 的指针和长度值 5 的 slice。

对于 Rust 的 .. range 语法,如果想要从索引 0 开始,可以不写两个点号之前的值。换句话说,如下两个语句是相同的:

let s = String::from("hello");

let slice = &s[0..2];
let slice = &s[..2];

依此类推,如果 slice 包含 String 的最后一个字节,也可以舍弃尾部的数字。这意味着如下也是相同的

let s = String::from("hello");

let len = s.len();

let slice = &s[3..len];
let slice = &s[3..];

也可以同时舍弃这两个值来获取整个字符串的 slice。所以如下亦是相同的:

let s = String::from("hello");

let len = s.len();

let slice = &s[0..len];
let slice = &s[..];

下面我们用字符串slice来实现从一个英文语句中找到第一个单词

fn main() {
    let s = String::from("hello world");

    let first_word = first_word(&s);

    println!("first_word = {}",first_word);
}

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!

    println!("the first word is: {}", word);

    s.clear(); //right
}

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[..]
}

回忆一下借用规则,当拥有某值的不可变引用时,就不能再获取一个可变引用。因为 clear 需要清空 String,它尝试获取一个可变引用。在调用 clear 之后的 println! 使用了 word 中的引用,所以这个不可变的引用在此时必须仍然有效。Rust 不允许 clear 中的可变引用和 word 中的不可变引用同时存在,因此编译失败。Rust 不仅使得我们的 API 简单易用,也在编译时就消除了一整类的错误!

二:字符串字面量slice

let s = "Hello, world!";

这里 s 的类型是 &str:它是一个指向二进制程序特定位置的 slice。这也就是为什么字符串字面量是不可变的;&str 是一个不可变引用。

对于上面定义的first_word函数

fn first_word(s: &String) -> &str {

可以修改成下面的定义,它使得可以对 String 值和 &str 值使用相同的函数,兼容性更强

fn first_word(s: &str) -> &str {
fn main() {
    let my_string = String::from("hello world");

    // `first_word` 接受 `String` 的切片,无论是部分还是全部
    let word = first_word(&my_string[0..6]);
    println!("1-word = {}", word);
    let word = first_word(&my_string[..]);
    println!("2-word = {}", word);
    // `first_word` 也接受 `String` 的引用,
    // 这等同于 `String` 的全部切片
    let word = first_word(&my_string);
    println!("3-word = {}", word);

    let my_string_literal = "hello world";

    // `first_word` 接受字符串字面量的切片,无论是部分还是全部
    let word = first_word(&my_string_literal[0..6]);
    println!("4-word = {}", word);
    let word = first_word(&my_string_literal[..]);
    println!("5-word = {}", word);

    // 因为字符串字面值**就是**字符串 slice,
    // 这样写也可以,即不使用 slice 语法!
    let word = first_word(my_string_literal);
    println!("6-word = {}", word);
}

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

运行结果:

三:数组slice

let a = [1, 2, 3, 4, 5];

let slice = &a[1..3];

这个 slice 的类型是 &[i32]。它跟字符串 slice 的工作方式一样,通过存储第一个集合元素的引用和一个集合总长度


http://www.kler.cn/a/550937.html

相关文章:

  • 深入解析 VIE(Variable Interest Entity,可变利益实体)架构:中国公司如何在海外上市?
  • Supabase全面介绍与使用指南
  • 【合集】Java进阶——Java深入学习的笔记汇总 再论面向对象、数据结构和算法、JVM底层、多线程、类加载、
  • Debezium同步之如何同步GIS数据
  • 字节跳动AI编辑器Trae基本配置教程
  • Retrofit+OkHttp+ViewModel
  • Web后端 Tomcat服务器
  • 基于pytest+requests+allure+yaml实现接口自动化测试框架
  • LeetCode 1287.有序数组中出现次数超过25%的元素:遍历
  • 【BUG】LLM|Ubuntu 用 ollama 部署 DeepSeek 但没输出,llama 有输出
  • 【第1章:深度学习概览——1.5 深度学习的核心组件与概念解析之损失函数与优化算法的选择】
  • OneCode 组件分类整理及枚举介绍
  • TensorFlow深度学习实战(8)——卷积神经网络
  • Spring MVC 的核心以及执行流程
  • Python实用技巧:轻松上手自动化数据爬取与存储
  • DeepSeek原理介绍以及对网络安全行业的影响
  • 计时器任务实现(保存视频和图像)
  • 【linux】在 Linux 上部署 DeepSeek-r1:32/70b:解决下载中断问题
  • 【机器学习】线性回归 多项式线性回归
  • 【MATLAB】解决mod函数、逻辑判断的误差问题