数组和切片
数组是一种存储在连续内存中的相同类型 T
的对象集合。 数组使用方括号 []
创建,其长度在编译时已知, 是其类型签名 [T; length]
的一部分。
切片类似于数组,但其长度在编译时未知。切片是一个双字对象: 第一个字是指向数据的指针,第二个字是切片的长度。字的大小与 usize 相同, 由处理器架构决定,例如在 x86-64 上是 64 位。切片可用于借用数组的一部分, 其类型签名为 &[T]
。
use std::mem; // 此函数借用一个切片。 fn analyze_slice(slice: &[i32]) { println!("切片的第一个元素:{}", slice[0]); println!("切片有 {} 个元素", slice.len()); } fn main() { // 固定大小的数组(类型签名是多余的)。 let xs: [i32; 5] = [1, 2, 3, 4, 5]; // 所有元素可以初始化为相同的值。 let ys: [i32; 500] = [0; 500]; // 索引从 0 开始。 println!("数组的第一个元素:{}", xs[0]); println!("数组的第二个元素:{}", xs[1]); // `len` 返回数组中元素的数量。 println!("数组中的元素数量:{}", xs.len()); // 数组是栈分配的。 println!("数组占用 {} 字节", mem::size_of_val(&xs)); // 数组可以自动借用为切片。 println!("将整个数组借用为切片。"); analyze_slice(&xs); // 切片可以指向数组的一部分。 // 它们的形式是 [起始索引..结束索引]。 // `起始索引` 是切片中的第一个位置。 // `结束索引` 是切片中最后一个位置的后一个位置。 println!("借用数组的一部分作为切片。"); analyze_slice(&ys[1 .. 4]); // 空切片 `&[]` 的示例: let empty_array: [u32; 0] = []; assert_eq!(&empty_array, &[]); assert_eq!(&empty_array, &[][..]); // 同样的操作,但更详细 // 可以使用 `.get` 安全地访问数组,它返回一个 `Option`。 // 可以像下面这样对其进行匹配,或者使用 `.expect()`。 // 如果你希望程序在访问越界时优雅地退出而不是继续执行, // 可以使用 `.expect()`。 for i in 0..xs.len() + 1 { // 糟糕,访问超出了数组范围! match xs.get(i) { Some(xval) => println!("{}: {}", i, xval), None => println!("慢着!{} 超出范围了!", i), } } // Out of bound indexing on array with constant value causes compile time error. //println!("{}", xs[5]); // Out of bound indexing on slice causes runtime error. //println!("{}", xs[..][5]); }