2.2 复合类型
复合类型表示一个变量可以保存多个值,这些值的类型如果不同,则是元祖类型,如果这些值的类型相同则是数组类型。
元祖类型可以表示某个物体的各种不同属性,可以使用不同的类型进行表达。例如:一个三口之间,每个人的姓名、身高和年龄。数组类型表示某个物体包含了固定长度的相同类型的不同数值或相同数值。例如:一个三口之家每个人的姓名或每个人的身高。
元祖和数组的区别:
特性 | 元组(Tuple) | 数组(Array) |
元素类型 | 可以不同(异构,如 (i32, f64, &str)) | 必须相同(同构,如 [i32; 3]) |
访问方式 | 通过索引(如 t.0)或模式匹配解构 | 通过索引(如 a[0])或切片操作 |
内存布局 | 元素可能不连续(类型不同导致内存对齐不同) | 元素连续存储(类型相同) |
迭代支持 | 需手动实现或转换为迭代器 | 原生支持迭代(如 for x in &array { ... }) |
常用场景 | 临时组合少量异构数据(如函数多返回值) | 存储同构数据集合(如固定大小的缓冲区) |
语法示例 | let t = (1, 3.14, "hello"); | let a = [1, 2, 3]; |
长度类型标注 | 不需要(通过元素推断) | 需标注(如 [i32; 5]) |
方法支持 | 无内置方法(需自行解构或处理) | 有内置方法(如 len(), map()) |
元祖和数组的相同点:
长度固定:两者在创建时,长度就固定了,无法扩展或缩小。
存储在栈上:默认情况下,两者的都是栈上保存的。
支持模式匹配:通过模式匹配进行结构或访问元素。
支持泛型和类型推导:编译器可以自行推导出他们的类型(部分情况下无法进行推导,系统会给出提示信息,这时就需要进行显示标识)。
- 元祖类型
将固定长度且不同类型的一组数据保存在一个变量内。
定义:let 变量名:(类型1,类型2, ...)=(变量1,变量2, ...);
fn main() {let person = ("曹操", 178.5, 40);println!("person:{:?}", person);}访问方法1:使用解构
fn main() {let person = ("曹操", 178.5, 40);let (name,height,age) = person;println!("name:{},height:{},age:{}", name, height, age);}访问方法2:使用下标
fn main() {let person = ("曹操", 178.5, 40);let name = person.0;let height = person.1;let age = person.2;println!("name:{},height:{},age:{}", name, height, age);}- 数组类型
将固定长度且相同类型的一组数据保存在一个变量内。
定义: let 数组变量名:[类型;长度]=[变量1,变量2, ...];
let 数组变量名=[变量;长度];
fn main() {let names:[&str;3] = ["曹操", "刘备", "孙权"];let ages=[10;5];println!("names: {:?}", names);println!("ages: {:?}", ages);}访问方法1:使用下标
fn main() {//使用下标访问数组中的元素let a = [1, 2, 3, 4, 5];let first = a[0];let second = a[1];println!("The first element is: {}", first);println!("The second element is: {}", second);} 访问方法2:使用切片
fn main() {//使用切片访问数组的元素let a = [1, 2, 3, 4, 5];let slice1 = &a[1..3];let slice2 = &a[1..];let slice3 = &a[..3];let slice4 = &a[..];println!("slice1: {:?}", slice1);println!("slice2: {:?}", slice2);println!("slice3: {:?}", slice3);println!("slice4: {:?}", slice4);}注意:当使用下标时,需要注意下标的索引值不可以超过数组的最大长度,否则系统会在编译时就报错,如果索引值不是直接获取的,而是经过计算或保存在其他变量中间接获取的,编译时虽然不会报错,但是运行时也会报错。
fn main() {//索引值超出数组范围let a = [1, 2, 3];let index = 10;let element = a[index];println!("The value of element is: {}", element);}系统报错信息:
--> src\main.rs:5:19|5 | let element = a[index];| ^^^^^^^^ index out of bounds: the length is 3 but the index is 10|= note: `#[deny(unconditional_panic)]` on by defaulterror: could not compile `lession02_02_06` (bin "lession02_02_06") due to 1 previous error间接获取的索引值
fn main() {//数组下标的索引值间接获取,编译时检测通过,但是运行时会越界let a = [1, 2, 3, 4, 5];let b = [1, 2, 6, 7, 8];println!("{:?}",a[b[2]]);}