【Rust自学】3.3. 数据类型:复合类型 3.3 数据类型复合类型3.3.0. 写在正文之前欢迎来到Rust自学的第三章一共有6个小节分别是:- 变量与可变性- 数据类型标量类型-数据类型复合类型本文- 函数和注释- 控制流if else- 控制流循环通过第二章的小游戏(没看的初学者强烈建议看一下)相信你已经学会了基本的Rust语法而在第三章我们将更深一层了解Rust中的通用的编程概念。3.3.1. 复合类型的简介复合类型可以将多个值组合成一个类型。Rust提供了两种基础的复合类型元组和数组。3.3.1. 元组Tuple元组的特点- 元组可以将多个不同类型的值组合成一个类型。- 元组的长度是固定的一旦声明就无法改变。创建元组- 在小括号里将值用逗号分开。- 元组中的每个位置都对应一个类型元组中各元素的类型不必相同。fn main(){ let tup: (u32, f32, i64) (6657, 0.0721, 114514); println!({},{},{}, tup.0, tup.1, tup.2); // Output: 6657,0.0721,114514 }获取元组元素值- 可以使用模式匹配来解构destructure一个元组从而获取元素值。fn main(){ let tup: (u32, f32, i64) (6657, 0.0721, 114514); let (x, y, z) tup; println!({},{},{}, x, y, z); // Output: 6657,0.0721,114514 }访问元组的元素- 在元组变量后使用点标记法后接元素的索引号。println!({},{},{}, tup.0, tup.1, tup.2);3.3.2. 数组数组的特点- 数组中的每个元素的类型必须相同。- 数组也可以将多个值放入一个类型。- 数组的长度是固定的。声明数组- 在中括号里各值用逗号分开。let a [1, 1, 4, 5, 1, 4];数组的用处- 如果想把数据放在栈Stack上而不是堆Heap上或者想保证有固定数量的元素这时使用数组更有好处。- 数组没有向量vector以后会讲灵活。- 向量由标准库提供而数组内置于语言中并通过prelude模块提供prelude也是标准库的一部分。- 向量的长度可以改变。- 不确定应该使用数组还是向量时大概率应该使用向量。数组的类型语法- 数组的类型以[类型; 长度]的形式表示。let machine: [u32; 4] [6, 6, 5, 7];声明数组的其他方法- 如果数组的每个元素值都相同那么可以- 在中括号里指定初始值- 然后跟着一个;- 最后加上数组的长度let a [3; 3]; let b [3, 3, 3];这个例子中a和b是等价的。访问数组的元素- 数组是栈上分配的一块连续内存。- 可以使用索引来访问数组的元素。let machine [6, 6, 5, 7]; let wjq machine[0];如果索引越界在编译器能够证明错误的情况下Rust可能在编译时发现它否则会在运行时panic因为Rust不允许程序继续读取该地址的内存数组背后是一块连续内存。假设数组的第一个元素在内存位置x那么第二个元素位于x 第一个元素的大小之后以此类推。如果索引大于数组的实际长度程序就会读取数组之外的内存而那里的内容可能是任意值。在C中完全没有边界检查。在C中普通数组也没有只有std::array有在Rust里强制进行边界检查。FeatureCCRustMemory modelContiguousContiguousContiguousSafetyNo bounds checkingstd::arrayhas bounds checking; ordinary arrays do notBounds checking is enforcedDynamic arraysManual memory management requiredstd::vectorVecMultidimensional arraysYesYesYesSpecial abilitiesSimple and efficientRich STL containersOwnership and borrow checking如果编译器能够证明索引越界就会在编译期拒绝该程序let a 5; let machine [6, 6, 5, 7]; let wjq machine[a]; // Error: this operation will panic at runtime如果索引要到运行时才能确定程序可以编译通过但越界访问会在运行时panicfn get_index() - usize { 5 // 设想这个值来自输入或其他地方 } fn main() { let machine [6, 6, 5, 7]; let wjq machine[get_index()]; }Output:thread main panicked at src/main.rs:7:15: index out of bounds: the len is 4 but the index is 5 note: run with RUST_BACKTRACE1 environment variable to display a backtrace