1. 数组 array
Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
let a = [1, 2, 3, 4, 5]; let a: [i32; 5] = [1, 2, 3, 4, 5]; let a = [3; 5]; let a = [3, 3, 3, 3, 3];
当你想要在栈(stack)而不是在堆(heap)上为数据分配空间,或者是想要确保总是有固定数量的元素时,数组非常有用。
正是因为array存储在stack上,所以必须固定大小。
2.切片 slice
slice是没有所有权的,它引用集合中一段连续的元素序列,而不用引用整个集合。
let a = [1, 2, 3, 4, 5]; let slice = &a[1..3];
3.基础类型字符串 str
str
本质也是表示一段 u8
序列,只是附带了额外的要求:这些 u8
序列必须是合法的 utf-8 编码
str
类型,也称为字符串切片(string slice),是最基本的字符串类型。它通常以借用的形式出现, 它们是一些储存在别处的 UTF-8 编码字符串数据的引用。它也是字符串字面值(string literals)的类型, 也就是 &'static str
。
字符串字面值:
这里 s
的类型是 &str
:它是一个指向二进制程序(binary executes)特定位置的 slice。这也就是为什么字符串字面值是不可变的;&str
是一个不可变引用。
&str
占用 16 个字节,除了 8 个字节代表其指向的第一个字节的地址之外,还有 8 个字节代表其所涵盖的字节长度(所以 &str
又被称为胖指针
4. 向量 vector
Vec
本质是一个指针,所以 Vec
变量是定长的,可以在Stack上存储;它指向Heap的一段具有相同类型的数据序列
5. String
String本质是Vec<u8>, 同str一样, 要求Heap中的u8序列是合法的utf编码
用代码查看类型
fn type_of<T>(_: T) -> &'static str { std::any::type_name::<T>() } fn main() { let x = 21; let y = 2.5; let strz = "abcd"; let str_slice = &strz[1..3]; let array_ref = b"abcd"; let array_slice = &array_ref[1..3]; let arr = [0x61 as u8, 0x62, 0x63, 0x64]; let arr_slice = &arr[1..3]; println!("{}", type_of(&y)); println!("{}", type_of(x)); println!("str= {}", type_of(strz)); println!("str slice= {}", type_of(str_slice)); println!("array ref ={}", type_of(array_ref)); println!("array slice= {}", type_of(array_slice)); println!("String={}", type_of(String::from(strz))); println!("array={}", type_of(arr)); println!("arr slice={}", type_of(arr_slice)); println!("vec={}", type_of(vec![0x61 as u8, 0x62, 0x63, 0x64])); println!("{}", type_of(main)); println!("{}", type_of(type_of::<u8>)); }
运行结果
&f64
i32
str= &str
str slice= &str
array ref =&[u8; 4]
array slice= &[u8]
String=alloc::string::String
array=[u8; 4]
arr slice=&[u8]
vec=alloc::vec::Vec<u8>
vexample::main
vexample::type_of<u8>