数组表达式和数组索引表达式

数组表达式

语法
数组表达式(ArrayExpression) :
   [ 数组元素(ArrayElements)? ]

数组元素(ArrayElements) :
      表达式(Expression) ( , 表达式(Expression) )* ,?
   | 表达式(Expression) ; 表达式(Expression)

数组表达式用于构造数组。数组表达式有两种形式。

第一种形式列出数组中的每个值。

这种形式的语法是,将类型统一的表达式列表用方括号括起来,表达式之间用逗号分隔。

这会按照表达式书写的顺序生成一个包含所有这些值的数组。

第二种形式的语法是,将由分号(;)分隔的两个表达式用方括号括起来。

; 之前的表达式称为 重复操作数(repeat operand)

; 之后的表达式称为 长度操作数(length operand)

它的类型必须是 usize,并且是一个常量表达式,例如字面量常量项

这种形式的数组表达式会创建一个长度为长度操作数的值的数组,其中每个元素都是重复操作数的一个副本。也就是说,[a; b] 创建一个包含 ba 值的副本的数组。

如果长度操作数的值大于 1,则要求重复操作数的类型是 Copy 类型,或者它必须是到常量项路径

当重复操作数是常量项时,它会被求值长度操作数的值次。

如果该值为 0,则常量项完全不会被求值。

对于不是常量项的表达式,它只会被求值一次,然后结果会被复制长度操作数的值次。

#![allow(unused)]
fn main() {
[1, 2, 3, 4];
["a", "b", "c", "d"];
[0; 128];              // array with 128 zeros
[0u8, 0u8, 0u8, 0u8,];
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]; // 2D array
const EMPTY: Vec<i32> = Vec::new();
[EMPTY; 2];
}

数组和切片索引表达式

语法
索引表达式(IndexExpression) :
   表达式(Expression) [ 表达式(Expression) ]

数组类型和切片类型的值可以通过在其后书写一个用方括号括起来的 usize 类型表达式(即索引)来索引。当数组是可变的时,结果内存位置可以被赋值。

对于其他类型,索引表达式 a[b] 等价于 *std::ops::Index::index(&a, b),或者在可变的 place 表达式上下文中等价于 *std::ops::IndexMut::index_mut(&mut a, b)。就像方法一样,Rust 也会反复在 a 上插入解引用操作,以找到实现。

对于数组和切片来说,索引是从零开始的。

数组访问是一个常量表达式,因此在使用常量索引值时,可以在编译时进行边界检查。否则,会在运行时执行检查,如果检查失败,会导致线程进入panic 状态

#![allow(unused)]
fn main() {
// lint is deny by default.
#![warn(unconditional_panic)]

([1, 2, 3, 4])[2];        // Evaluates to 3

let b = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
b[1][2];                  // multidimensional array indexing

let x = (["a", "b"])[10]; // warning: index out of bounds

let n = 10;
let y = (["a", "b"])[n];  // panics

let arr = ["a", "b"];
arr[10];                  // warning: index out of bounds
}

数组索引表达式可以通过为数组和切片之外的其他类型实现 IndexIndexMut traits 来实现。