数组类型
收集多个值的另一种方法是使用数组。与元组不同,数组的每个元素都必须具有相同的类型。Rust中的数组与某些其他语言中的数组不同,因为Rust中的数组具有固定长度,例如元组。
在Rust中,进入数组的值被写成方括号内的逗号分隔列表:
文件名:src / main.rs
fn main() {let a = [1, 2, 3, 4, 5];}
当您希望将数据分配在堆栈而不是堆上时(当我们在第4章中讨论堆栈和堆时),或者要确保始终拥有固定数量的元素时,数组很有用。但是,数组不像矢量类型那样灵活。载体是由标准库提供一个类似集合类型是允许生长或尺寸的缩小。如果不确定使用数组还是向量,则可能应该使用向量。第8章将更详细地讨论向量。
一个程序可能需要使用数组而不是向量的一个例子是,该程序需要知道一年中各个月份的名称。这样的程序不太可能需要添加或删除月份,因此您可以使用数组,因为您知道它将始终包含12个元素:
let months = ["January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December"];
您将使用方括号编写数组的类型,并且在方括号内包括每个元素的类型,分号以及数组中元素的数量,如下所示:
let a: [i32; 5] = [1, 2, 3, 4, 5];
在这里,i32是每个元素的类型。分号后的数字5 表示数组包含五个元素。
以这种方式编写数组的类型看起来类似于初始化数组的另一种语法:如果要创建一个数组,该数组的每个元素都包含相同的值,则可以指定初始值,后跟一个分号,然后指定长度数组放在方括号中,如下所示:
let a = [3; 5];
名为的数组a将包含5将全部设置为3初始值的元素 。这与写作相同,let a = [3, 3, 3, 3, 3];但更为简洁。
访问数组元素
数组是在堆栈上分配的单个内存块。您可以使用索引访问数组的元素,如下所示:
文件名:src / main.rs
fn main() {let a = [1, 2, 3, 4, 5];let first = a[0];let second = a[1];}
在此示例中,名为的变量first将获得值1,因为这是[0]数组中index处的值。名为的变量second将从数组中的2索引获取值[1]。
无效的数组元素访问
如果您尝试访问超出数组末尾的数组元素,会发生什么情况?假设您将示例更改为以下代码,这些代码将编译但运行时会退出并显示错误:
文件名:src / main.rsfn main() { let a = [1, 2, 3, 4, 5]; let index = 10; let element = a[index]; println!("The value of element is: {}", element); }
使用运行此代码将cargo run产生以下结果:
$ cargo runCompiling arrays v0.1.0 (file:///projects/arrays)Finished dev [unoptimized + debuginfo] target(s) in 0.31sRunning `target/debug/arrays`thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10'
, src/main.rs:5:19note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
编译没有产生任何错误,但是程序导致 运行时错误,并且没有成功退出。当您尝试使用索引访问元素时,Rust将检查您指定的索引是否小于数组长度。如果索引大于或等于数组长度,Rust将惊慌。
这是Rust实施安全原则的第一个例子。在许多低级语言中,不会执行这种检查,并且当您提供错误的索引时,可以访问无效的内存。Rust通过立即退出而不是允许内存访问并继续运行来保护您免受此类错误的侵害。
