Rust数组
在本章中,我们将学习数组及其相关的各种功能。在学习数组之前,让我们看一下数组与变量的区别。
变量具有以下限制:
变量本质上是标量。换句话说,变量声明一次只能包含一个值,这意味着要在程序中存储n个值,将需要n个变量声明。因此,当需要存储更大的值集合时,使用变量是不可行的。
程序中的变量在内存中随机分布,因此很难按声明的顺序检索值。
数组是值的同类集合,简而言之,数组是相同数据类型的值的集合。
数组的特点
数组的特点如下:
数组会分配一段连续的内存块;
数组是大小固定的,这意味着数组一旦初始化就无法调整大小;
每个存储块代表一个数组元素;
数组元素由唯一的整数标识(称为元素的下标/索引);
填充数组元素称为数组初始化;
数组元素值可以更新或修改,但不能删除。
声明和初始化数组
使用下面给出的语法在Rust中声明和初始化一个数组。
语法
//语法1 let variable_name = [value1,value2,value3]; //语法2 let variable_name:[dataType;size] = [value1,value2,value3]; //语法3 let variable_name:[dataType;size] = [default_value_for_elements,size];
在第一种语法中,数组的类型是由数组第一个元素的数据类型推断出来的。
例子:简单数组
下面的示例显式指定数组的大小和数据类型,println!()宏中的{:?}用于打印数组中的所有值, len函数返回计算数组的大小。
fn main(){ let arr:[i32;4] = [10,20,30,40]; println!("array is {:?}",arr); println!("array size is :{}",arr.len()); }
array is [10, 20, 30, 40] array size is :4
例子:没有数据类型的数组
以下程序声明了一个由4个元素组成的数组,在变量声明期间未明确指定数据类型,在这种情况下,数组将为整数类型。
fn main(){ let arr = [10,20,30,40]; println!("array is {:?}",arr); println!("array size is :{}",arr.len()); }
array is [10, 20, 30, 40] array size is :4
例子:默认值
以下示例创建一个数组,并使用默认值-1初始化所有元素。
fn main() { let arr:[i32;4] = [-1;4]; println!("array is {:?}",arr); println!("array size is :{}",arr.len()); }
array is [-1, -1, -1, -1] array size is :4
例子:使用for循环遍历数组
下面的示例展示数组的遍历,打印索引及其对应的值。
循环从索引0到3(最后一个数组元素的索引)中检索值。
fn main(){ let arr:[i32;4] = [10,20,30,40]; println!("array is {:?}",arr); println!("array size is :{}",arr.len()); for index in 0..4 { println!("index is: {} & value is : {}",index,arr[index]); } }
array is [10, 20, 30, 40] array size is :4 index is: 0 & value is : 10 index is: 1 & value is : 20 index is: 2 & value is : 30 index is: 3 & value is : 40
例子:使用iter()函数
iter()函数获取数组中所有元素的值。
fn main(){ let arr:[i32;4] = [10,20,30,40]; println!("array is {:?}",arr); println!("array size is :{}",arr.len()); for val in arr.iter(){ println!("value is :{}",val); } }
array is [10, 20, 30, 40] array size is :4 value is :10 value is :20 value is :30 value is :40
例子:可变数组
mut 关键字可用于声明可变数组。
下面的示例声明一个可变数组,并修改第二个数组元素的值。
fn main(){ let mut arr:[i32;4] = [10,20,30,40]; arr[1] = 0; println!("{:?}",arr); }
[10, 0, 30, 40]
将数组作为参数传递给函数
数组可以按值或引用传递给函数。
例子:按值传递
fn main() { let arr = [10,20,30]; update(arr); print!("Inside main {:?}",arr); } fn update(mut arr:[i32;3]){ for i in 0..3 { arr[i] = 0; } println!("Inside update {:?}",arr); }
Inside update [0, 0, 0] Inside main [10, 20, 30]
例子:引用传递
fn main() { let mut arr = [10,20,30]; update(&mut arr); print!("Inside main {:?}",arr); } fn update(arr:&mut [i32;3]){ for i in 0..3 { arr[i] = 0; } println!("Inside update {:?}",arr); }
Inside update [0, 0, 0] Inside main [0, 0, 0]
数组声明和常量
让我们考虑下面给出的示例,以了解数组声明和常量。
fn main() { let N: usize = 20; let arr = [0; N]; //错误:与常量一起使用的非常量 print!("{}",arr[10]) }
编译器将导致异常,因为在编译时必须知道数组的长度,但此处变量“ N”的值将在运行时确定。因此,变量不能用于定义数组的大小。
但是,以下程序有效:
fn main() { const N: usize = 20; //指针大小 let arr = [0; N]; print!("{}",arr[10]) }
带有const关键字前缀的标识符的值在编译时定义,并且在运行时无法更改。 usize是指针大小的,因此其实际大小取决于你要为其编译程序的机器。