Rust-数组

数组是一个容器,它在一块连续空间内存中,存储了一系列的同样类型的数据。

数组中元素的占用空间大小必须是编译期确定的。

数组本身所容纳的元素个数也必须是编译期确定的,执行阶段不可变。

如果需要使用变长的容器,可以使用标准库中的Vec/LinkedList等。数组类型的表示方式为[T;n]。

其中T代表元素类型;n代表元素个数;它必须是编译期常量整数;中间用分号隔开。

下面看一个基本的示例:

多维数组

既然[T;n]是一个合法的类型,那么它的元素T当然也可以是数组类型,因此[[T;m];n]类型自然也是合法类型。示例如下:

数组切片

对数组取借用borrow操作,可以生成一个"数组切片"(Slice)。

数组切片对数组没有"所有权",我们可以把数组切片看作专门用于指向数组的指针,是对数组的另外一个"视图"。

比如,我们有一个数组[T;n],它的借用指针的类型就是&[T;n]。

它可以通过编译器内部魔法转换为数组切片类型&[T]。

数组切片实质上还是指针,它不过是在类型系统中丢弃了编译阶段定长数组类型的长度信息,而将此长度信息存储为运行期的值。示例如下:

DST和胖指针

从前面的示例中可以看到,数组切片是指向一个数组的指针,而它比指针又多了一点东西------它不止包含有一个指向数组的指针,切片本身还含带长度信息。

Slice与普通的指针是不同的,它有一个非常形象的名字:胖指针(fat pointer)。

与这个概念相对应的概念是"动态大小类型"(Dynamic Sized Type,DST)。

所谓的DST指的是编译阶段无法确定占用空间大小的类型。为了安全性,指向DST的指针一般是胖指针。

比如:对于不定长数组类型[T],有对应的胖指针&[T]类型;对于不定长字符串str类型,有对应的胖指针αstr类型;以及在后文中会出现的Trait Object;等等。

由于不定长数组类型[T]在编译阶段是无法判断该类型占用空间的大小的,目前我们不能在栈上声明一个不定长大小数组的变量实例,也不能用它作为函数的参数、返回值。

但是,指向不定长数组的胖指针的大小是确定的,&[T]类型可以用做变量实例、函数参数、返回值。

通过前面的示例我们可以看到,&[T]类型占用了两个指针大小的内存空间。

Range

Rust中的Range代表一个"区间",一个"范围",它有内置的语法支持,就是两个小数点...。示例如下:

边界检查

在前面的示例中,我们的"索引"都是一个合法的值,没有超过数组的长度。如果我们给"索引"一个非法的值会怎样呢:

编译通过,执行thread'main'panicked at index out of bounds:the len is 5 but the index is10'。

可以看出,如果用/test10,则会出现数组越界,Rust目前还无法任意索引执行编译阶段边界检查,但是在运行阶段执行了边界检查。下面我们分析一下边界检查背后的故事。

在Rust中,"索引"操作也是一个通用的运算符,是可以自行扩展的。

如果希望某个类型可以执行"索引"读操作,就需要该类型实现std::ops::Index trait,如果希望某个类型可以执行"索引"写操作,就需要该类型实现std::ops::IndexMut trait。

对于数组类型,如果使用usize作为索引类型执行读取操作,实际执行的是标准库中的以下代码:

字符串

字符串是非常重要的常见类型。相比其他很多语言,Rust的字符串显得有点复杂,主要是跟所有权有关。Rust的字符串涉及两种类型,一种是&str,另外一种是string。

&str

str是Rust的内置类型。&str是对str的借用。Rust的字符串内部默认是使用utf-8编码格式的。而内置的char类型是4字节长度的,存储的内容是Unicode Scalar Value。

所以,Rust里面的字符串不能视为char类型的数组,而更接近u8类型的数组。

实际上str类型有一种方法:fn as_ptr(&self)->*const u8。

它内部无须做任何计算,只需做一个强制类型转换即可。

String

接下来讲string类型。它跟&str类型的主要区别是,它有管理内存空间的权力。

关于"所有权"和"借用"的关系,&str类型是对一块字符串区间的借用,它对所指向的内存空间没有所有权,哪怕&mut str也一样。比如:

let greeting:&str ="Hello";

我们没办法扩大greeting所引用的范围,在它后面增加内容。但是string类型可以。示例如下:

相关推荐
灵槐梦12 分钟前
【速成51单片机】2.点亮LED
c语言·开发语言·经验分享·笔记·单片机·51单片机
想睡觉 . 我也想睡觉 .13 分钟前
【C++算法】1.【模板】前缀和
开发语言·c++·算法
it噩梦18 分钟前
深度分析 es multi_match 中most_fields、best_fields、cross_fields区别
java·elasticsearch
好看资源平台18 分钟前
Java Web开发基础——Web应用的请求与响应机制
java
刘Java21 分钟前
Dubbo 3.x源码(28)—Dubbo服务发布导出源码(7)应用级服务接口元数据发布
java·dubbo·dubbo源码
---wzy---22 分钟前
我的JAVA-Web基础(2)
java·开发语言
伟大无须多言33 分钟前
企业资源规划系统(ERP)服务器上线项目实施指南
开发语言·php
逊嘘34 分钟前
【Java数据结构】LinkedList
java·开发语言·数据结构
周盛欢35 分钟前
云服务器yum无法解析mirrorlist.centos.org
开发语言·python
总是学不会.36 分钟前
第五篇:前后端如何“扯皮”——HTTP 在开发中的应用
java·网络·网络协议·http·开发