老前端学Rust - 第四章(切片)

兄弟们,正反馈越来越差了。。第一章还能有互动的,第二章就开始没有了。怪不到坚持写下去的人那么少。。希望看过的小伙伴能留下足迹~疑问也好吐槽也罢,或者给咱提提建议。

另外扯个闲篇,上次不是说自行车嘛,然后我买了辆自行车,骑了几次,心率上的太快了。。。随便骑骑心率直奔150+。。。前两天骑了20几分钟心率太高就坐着休息了下,结果降到一百零几的时候突然感觉难受,然后心慌难受,心率在没运动的时候直接上到150+,当时感觉人都要没了,浑身发冷、没力气、心慌,第一次感觉离猝死那么近。。。后来打了个车去医院的路上缓下来了就没去。。但是在家平躺都还是120,110,一直到睡到早上才缓过来。。准备挂个心内专家号看看了。兄弟们,真的身体要紧,天天待电脑跟前人要废了。公司是老板的,身体才是自己的。

好了,书接上回,第三章讲到rust最核心也是最基础的概念 - 《所有权》,最后讲到引用这一块,可以通过引用,去在不持有所有权的情况下传递和修改变量等。除了引用,Rust还有另外一种不持有所有权的数据类型 - 切片


切片

切片允许我们引用集合中某一段连续的元素序列,而不是整个集合。

假设我们要获取某个字符串的首个单词作为结果返回,这个函数要怎么写?

e.g.

rust 复制代码
fn first_word(s: &String) -> usize {
    let bytes = s.as_bytes(); // 将s转换为字节数组
    
    // 迭代器
    for (i, &item) in bytes.iter().emumerate() {
        // 判断代表空格的字节
        if item == b' ' {
            return i;
        }
    }
    
    s.len()
}

上面这个函数中有目前我们没学到的迭代器等,不过代码咱肯定看得懂意思,就是先转成字节数组,然后遍历,找到字节为空格的就返回当前位置。

这个函数就是实现了期望功能的函数,它能成功的搜索并返回字符串中第一个单词结尾处的位置索引,如果没有空格就返回字符串长度。但是他有一个问题,他将一个usize独立返回出来,这个usize在脱离s之后就毫无意义。

e.g.

rust 复制代码
fn main() {
    let mut s = String::from("hello world");
    
    let word = first_word(&s);  // 返回5
    
    s.clear(); // 清空当前字符串
}

上面我们调用first_word获取了&s的第一个单词的位置索引,返回5,然后在下一行清空了字符串,由于5这个位置虽然在我们思维上是与s关联的,但是其实并没有真正的有关联,所以这个word其实就失去了任何意义。 所以我们得找一个方案让他们真正有关联。


字符串切片

字符串切片是指向String对象中某个连续部分的引用。

rust 复制代码
let s = String::from("hello world");

let hello = &s[0..5]; // hello
let world = &s[6..11]; // world
let all = &s[..];   // hello world

上面的语法就表示一段连续内存的一个视图,起始位置和结束位置用[]表示(左闭右开),这里额外再讲一点,上面s,hello,world,all这几个都是指向某一个内存地址,其中s, hello, all指向的都是同一块内存地址,而world不是,他指向的是w字节对应的内存地址。

如此,我们就可以重新改造下first_word函数:

rust 复制代码
fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();
    
    for (i, &item) in bytes.iter().enumerate() {
        if item == b'' {
            return &s[..i];
        }
    }
    
    return [..]
}

字符串字面量就是切片

我们之前使用过的字符串的字面量其实就是一个字符串切片,他是&str类型,指向二进制程序中一个特定位置的切片。

e.g.

rust 复制代码
let s: &str = "hello world";
let s1: &'static str = "hello world";
let s2: String = s1.to_string(); 
let s3: &String = &s2; 
let s4: &str = &s2[..];

有个小细节要提醒下,&'static str这是静态数据区中的字符串的表示方法,表示s1是一个静态数据区中的字符串的切片。字符串字面量默认会存放在静态数据区里,而静态数据区中的字符串总是贯穿程序运行的整个生命期,直到程序结束的时候才会被释放。上面的例子中,s,s1指向静态数据区,s2指向堆内存,s3是s2的引用,指向的也是堆内存,s4是s2的切片引用,指向的也是同一个堆内存地址。

字符串类型String和&str是可以转换的

e.g.

rust 复制代码
let s: String = String::from("hello world");
let s1: &str = s.as_str();
let s2: String = s1.to_string();

其他类型的切片

其实我们first_word中的let bytes = s.as_bytes()这段代码,bytes就是&[u8]类型的切片,表示一个字节串的切片。

rust 复制代码
let a:[i32; 5] = [1,2,3,4,5];
let slice = &a[1..3];

上面这个例子的切片类型就是&[i32],它内部存储了一个指向起始元素的引用及长度。还有其他各种各样的集合会使用切片类型,用泛型的表示法就表示为&[T],T表示任意数组或向量的集合。

OK,本章结束,所有权相关的也就结束了。期望兄弟们动动小手,给点反馈毕竟这种文章本来面向的读者范围就很小了,不像那些面经啥的,随便写写一堆人点赞、评论啥的我还是想跟小伙伴们互动互动,一个人学也很无聊的。。。

相关推荐
崔庆才丨静觅2 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅3 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅4 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅4 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax