• rust数组


    一、定义数组

    (一)一维数组
    1.指定所有元素
    语法格式

    let variable_name: [dataType; size] = [value1,value2,value3];
    
    • 1

    例如

    let arr: [i32; 4] = [10,20,30,40];
    
    • 1

    2.指定初始值和长度
    所有元素具有相同的值
    语法格式

    let variable_name: [dataType; size] = [value; size];
    
    • 1

    例如

    let arr: [i32;4] = [-1;4];
    
    • 1

    注意
    数组的长度必须在编译时就是已知的,而且编译后是固定不变的。因此声明数组时长度必须是整数字面量或者整数常量。
    如果数组长度是一个变量,则会编译错误。例如下面的代码

    fn main() {
         let N: usize = 20;
         let arr = [0; N]; //错误: non-constant used with constant
         print!("{}",arr[10])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果我们将 let 关键字修改为 const 关键字,编译就能通过了。

    fn main() {
         const N: usize = 20;
         let arr = [0; N];     // 固定大小
         print!("{}",arr[10])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.省略数组类型

    let variable_name = [value1,value2,value3];
    let variable_name = [value; size];
    
    • 1
    • 2

    例如

    let arr = [10,20,30,40];
    let arr = [-1;4];
    
    • 1
    • 2

    4.可变数组
    在上面几种方式基础上添加mut关键字。
    例子

    fn main(){
         let mut arr:[i32;4] = [10,20,30,40];
         arr[1] = 0;
         println!("{:?}",arr);
    }
    输出结果如下
    [10, 0, 30, 40]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (二)二维数组
    1.指定所有元素
    语法格式

    let var: [[type; size1]; size2] = [[value1, value2...], ...];
    
    • 1

    例子

    let directions: [[i32; 2]; 4] = [[-1, 0], [0, 1], [0, 1], [1, 0]];
    
    • 1

    2.指定初始值和长度
    语法格式

    let var: [[type; size1]; size2] = [[value; size1]; size2];
    
    • 1

    例子

    let directions: [[i32; 2]; 4] = [[0; 2]; 4];
    
    • 1

    3.省略类型
    语法格式

    let var = [[value1, value2...], ...];
    let var = [[value; size1]; size2];
    
    • 1
    • 2

    例子

    let directions = [[-1, 0], [0, 1], [0, 1], [1, 0]];
    let directions = [[0u8; 4]; 4];
    
    • 1
    • 2

    4.可变二维数组
    在上面几种方式基础上添加mut

    数组分配在栈上,但Rust中,栈的大小是有限制的。比如Linux下默认为8M,Windows下默认为2M。这太小了不够用。我们可以利用Box,将数组分配到堆上。

    二、使用数组

    (一)数组长度len()
    len()用于返回数组的长度。
    例子

    fn main() {
        let arr:[i32;4] = [-1;4];
        println!("{}",arr.len());
        let directions: [[i32; 2]; 4] = [[0; 2]; 4];
        println!("{} {}", directions.len(), directions[0].len());
    }
    输出结果如下
    4
    4 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (二)访问数组元素

    let mut nums1 = [1; 5];
    nums1[1] = 4;
    println!("{}", nums1[1]);
    
    • 1
    • 2
    • 3

    (三)遍历数组
    1.使用索引

    let mut nums1 = [1; 5];
    for i in 0..nums1.len() {
        println!("{} ", nums1[i]);
    }
    for i in 0..nums1.len() {
        nums1[i] = i;
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.直接使用数组

    for num in nums1 {
         print!("{} ", num);
    }
    println!();
    
    • 1
    • 2
    • 3
    • 4

    3.使用数组的引用

    let mut nums1 = [1; 5];
    let mut i = 0;
    for num in &nums1 {
        print!("{} ", num);
    }
    println!();
    for num in &mut nums1 {
        *num = i;
        i += 1;
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.使用数组的迭代器
    iter()返回一个只读迭代器

    for num in nums1.iter() {
         print!("{} ", num);
    }
    println!();
    
    • 1
    • 2
    • 3
    • 4

    iter_mut()返回一个可写迭代器

    let mut nums1 = [1; 5];
    let mut i = 0;
    for num in nums1.iter_mut() {
         *num = i;
         i += 1;
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    into_iter()返回一个迭代器,但是转让所有权

    let mut nums1 = [1; 5];
    for num in nums1.into_iter() {
        print!("{} ", num);
    }
    println!();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    for num in nums1
    实际上等价于
    for num in nums1.into_iter()

    5.使用迭代器的enumerate

    let mut nums1 = [1; 5];
    for (pos, v) in nums1.iter().enumerate() {
        println!("nums[{}]={}", pos, v);
    }
    println!("{:?}", nums1);
    for (pos, v) in nums1.iter_mut().enumerate() {
        *v=pos;
        println!("nums[{}]={}", pos, v);
    }
    println!("{:?}", nums1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二维数组遍历:
    1.使用索引

    let mut grid = [[0; 5]; 5];
    for i in 0..grid.len() {
        for j in 0..grid[i].len() {
             grid[i][j] = j;
             print!("{} ", grid[i][j]);
        }
        println!();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.使用引用

    let mut grid = [[0; 5]; 5];
    for row in &grid {
        for col in row {
             print!("{} ", col);
        }
        println!();
    }
    let mut i = 0;
    for row in &mut grid{
        for col in row {
             *col = i;
             i += 1;
             print!("{} ", col);
        }
        println!();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.使用迭代器

    let mut grid = [[0; 5]; 5];
    for row in grid.iter() {
        for col in row.iter() {
             print!("{} ", col);
        }
        println!();
    }
    let mut i = 0;
    for row in grid.iter_mut(){
        for col in row.iter_mut() {
             *col = i;
             i += 1;
             print!("{} ", col);
        }
        println!();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.使用迭代器的enumerate

    let mut grid = [[0; 5]; 5];
    for (i, row) in grid.iter().enumerate() {
        for (j, col) in row.iter().enumerate() {
             print!("{}", col);
        }
        println!()
    }
    for (i, row) in grid.iter_mut().enumerate() {
        for (j, col) in row.iter_mut().enumerate() {
             *col = 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (四)转换数组

    pub fn map(self, f: F) -> [U; N]
    where
    F: FnMut(T) -> U,
    
    • 1
    • 2
    • 3

    返回一个相同长度的数组,它的元素是由原数组元素应用f函数得到的。
    如果您需要动态大小的向量,请使用Iterator::map。
    关于性能和栈使用的注意事项
    尽量避免在大数组上使用此方法。还要尽量避免连续使用map (例如arr.map(…).map(…))。
    尽量使用Iterator::map,只有真正需要一个大小相同的新数组时,才使用[T; N]::map。
    例子

    let x = [1, 2, 3];
    let y = x.map(|v| v + 1);
    assert_eq!(y, [2, 3, 4]);
    let x = [1, 2, 3];
    let mut temp = 0;
    let y = x.map(|v| { temp += 1; v * temp });
    assert_eq!(y, [1, 4, 9]);
    let x = ["Ferris", "Bueller's", "Day", "Off"];
    let y = x.map(|v| v.len());
    assert_eq!(y, [6, 9, 3, 3]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (五)数组排序
    因为数组能隐式转换成切片,所以切片的方法,数组都能使用。
    sort()与sort_unstable()
    首选sort_unstable,因为它比sort()快,并且不分配辅助内存。
    例子

    let mut v = [-5, 4, 1, -3, 2];
    v.sort();
    assert!(v == [-5, -3, 1, 2, 4]);
    
    • 1
    • 2
    • 3

    sort_by()与sort_unstable_by()
    指定比较函数
    首选sort_unstable_by(),因为它比sort_by()快,并且不分配辅助内存。
    例子

    let mut v = [5, 4, 1, 3, 2];
    v.sort_by(|a, b| a.cmp(b));
    assert!(v == [1, 2, 3, 4, 5]);
    // 反向排序
    v.sort_by(|a, b| b.cmp(a));
    assert!(v == [5, 4, 3, 2, 1]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    sort_by_key()与sort_unstable_by_key()
    指定键函数
    首选sort_unstable_by_key(),因为它比sort_by_key()快,并且不分配辅助内存。
    例子

    let mut v = [-5i32, 4, 1, -3, 2];
    v.sort_by_key(|k| k.abs());
    assert!(v == [1, 2, -3, 4, -5]);
    
    • 1
    • 2
    • 3

    (七)其他常用方法

    分割数组
    let (part1, part2) = [1,2,3,4,5].split_at(2);
    println!("part1={:?}", part1);//[1,2]
    println!("part2={:?}", part2);//[3,4,5]
    
    交换数组元素
    let mut arr = [1,2,3,4];
    arr.swap(1,2);
    println!("arr: {:?}", arr);//[1, 3, 2, 4]
    
    逆转数组
    arr.reverse();
    println!("arr: {:?}", arr);//[4, 2, 3, 1]
    
    //二分查找
    let index: Result = [1,2,3,4,5].binary_search(&4);
    //index: Ok(3)
    println!("index: {:?}", index);
    
    最后一个元素
    let last_elem: Option<&i32> = [1,2,3,4,5].last();
    //last elem: Some(5)
    println!("last elem: {:?}", last_elem);
    
    数组求和
    let array: [i32; 10] = [1; 10];
    assert_eq!(10, array.iter().sum::());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    (八)数组作为函数参数
    数组可以作为函数的参数。而传递方式有 传值传递 和 引用传递 两种方式。
    传值传递 就是传递数组的一个副本给函数做参数,函数对副本的任何修改都不会影响到原来的数组。
    引用传递 就是传递数组在内存上的位置给函数做参数,因此函数对数组的任何修改都会影响到原来的数组。

    范例:传值传递

    fn main() {
         let arr = [10,20,30];
         update(arr);
         println!("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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    范例2: 引用传递

    fn main() {
         let mut arr = [10,20,30];
         update(&mut arr);
         println!("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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    机械臂示教轨迹参数化方法 DMP, Dynamic Movement Primitive (一)
    mp4视频批量截取!!!
    Java面试题大全(整理版)1000+面试题附答案详解,最全面详细,看完稳了
    gRPC-go 元数据
    java8 Optional理解及示例
    2023年9月青少年软件编程(C 语言) 等级考试试卷(一级)
    nginx模块
    【小沐学前端】Node.js实现基于Protobuf协议的UDP通信(UDP/TCP)
    C# 设计保存文件
    我和谷歌共成长——前端必备插件Vue.js devtools
  • 原文地址:https://blog.csdn.net/inxunxun/article/details/132942692