写点什么

每日一 R「11」数据结构(二)切片

作者:Samson
  • 2022 年 8 月 20 日
    上海
  • 本文字数:1161 字

    阅读完需:约 4 分钟

每日一R「11」数据结构(二)切片

今天要学习的数据结构是集合容器。像其他语言一样,容器例如数组、列表,是非常重要的数据结构。其实,只要是把某些特定的数据封装在某个数据结构中,这个数据结构就能称为容器。例如 Option<T> 封装了存在(Some)或不存在(None)的容器。例如上节学习的 Cow,它也能看作是一个容器,封装了数据 B 的借用(Borrow)或所有权(Owned)。


容器中有一类特别重要,就是集合容器。今天我们学习的主角就是集合容器,例如:


  • 字符串、数组、列表、哈希表等

  • 切片

  • VecDeque<T> 循环缓冲区、LinkedList<T> 双向队列等


今天我们主要学习切片及相关的容器。

01-切片

Rust 中,切片是描述同一类型、长度不定、连续存放的一组数据,用 [T] 表示,它与定长数组的表示方式有点类似 [T; n]。切片是典型的 DST(Dynamically Sized Type),另外一个典型是 trait object。


切片常见的用法有:


  • &[T],只读引用

  • &mut [T],可变引用

  • Box<T>,分配在堆上的切片


课程中有一幅图片,形象地展示了切片与数据结构的关系:



02-切片和 Iterator

切片和 Iterator 经常配合在一起使用。切片是集合数据的视图,而 Iterator 定义了对集合数据的各种操作。切片实现了 iter() 方法,可以获得切片的迭代器,对切片进行迭代。


Iterator trait 最关键的是 next() 方法和 Item 关联类型。


  • Item 定义了迭代器取出来的元素类型

  • next() 定义了迭代器迭代下一个值的方法,返回 None 时证明迭代器迭代完毕


Rust 中的迭代器一般都支持链式写法,而且迭代器是 lazy 的,即知道运行到 collect 这类方法时才真正开始执行整个链。而且 Rust 对链式调用加入了 inline 优化,以提高其执行效率。

03-&str 是一个特殊的切片

String 是一个特殊的结构,其内部通过 Vec<u8> 存储数据。对 String 进行切片,得到的切片为 &str。


String、&String、&str 的关系,通过一幅图来区别:



04-Box<[T]>

Box<[T]> 是一个特殊的结构。它与 Vec<T>的区别如下:



Vec<T> 在栈上的胖指针包含三部分内容,地址、容量和长度;而 Box<[T]> 在栈上的胖指针只包含两部分,地址和长度。


Box<[T]> 与 &[T] 有什么区别呢?


  • Box<[T]> 内存分配在堆上,及栈上胖指针指向的永远是堆中的某块地址。

  • &[T] 指向的地址可能在堆上、也可能在栈上

  • Box<[T]> 具有所有权,而 &[T] 仅是个只读借用

  • 目前生成 Box<[T]> 的方式只有一种,即


    let v = vec![1, 2, 3, 4];    let b: Box<[i32]> = v.into_boxed_slice();  // 
复制代码


本节课程链接:《16|数据结构:Vec<T>、&[T]、Box<[T]> ,你真的了解集合容器么?


历史文章推荐

每日一 R「10」数据结构(一)智能指针

每日一 R「09」类型系统(三)

每日一 R「08」类型系统(二)

每日一 R「07」类型系统(一)

每日一 R「06」内存管理

每日一 R「05」生命周期

每日一 R「04」常用的智能指针

每日一 R「03」Borrow 语义与引用

每日一 R「02」所有权与 Move 语义

每日一 R「01」跟着大佬学 Rust

发布于: 刚刚阅读数: 4
用户头像

Samson

关注

还未添加个人签名 2019.07.22 加入

还未添加个人简介

评论

发布
暂无评论
每日一R「11」数据结构(二)切片_8月日更_Samson_InfoQ写作社区