在Rust中创建二维数组

时间:2012-11-03 18:31:15

标签: arrays vector multidimensional-array rust

如何在Rust中创建一个空的可变二维数组?

这是我到目前为止所尝试的:

let mut state[[u8 * 4] * 4];

这会产生错误

error: expected one of `:`, `;`, `=`, or `@`, found `[`
 --> src/main.rs:2:18
  |
2 |     let mut state[[u8 * 4] * 4];
  |                  ^ expected one of `:`, `;`, `=`, or `@` here

10 个答案:

答案 0 :(得分:39)

在Rust 1.0中,以下工作:

let mut state = [[0u8; 4]; 6];
state[0][1] = 42;

请注意,内部段的长度是该类型的组成部分。例如,您可以按如下方式引用(并传递)state

let a: &[[u8; 4]] = &state;

但并非没有指定子阵列的固定长度。如果您需要可变长度的子阵列,您可能需要执行以下操作:

let x: [Box<[u8]>; 3] = [
    Box::new([1, 2, 3]),
    Box::new([4]), 
    Box::new([5, 6])
];
let y: &[Box<[u8]>] = &x;

答案 1 :(得分:10)

您可以像这样创建动态大小的2D矢量:

fn example(width: usize, height: usize) {
    // Base 1d array
    let mut grid_raw = vec![0; width * height];

    // Vector of 'width' elements slices
    let mut grid_base: Vec<_> = grid_raw.as_mut_slice().chunks_mut(width).collect();

    // Final 2d array
    let grid: &mut [&mut [_]] = grid_base.as_mut_slice();

    // Accessing data
    grid[0][0] = 4;
}

答案 2 :(得分:8)

  

编者注:这个答案早于Rust 1.0,并且一些概念和语法已经改变。其他答案适用于Rust 1.0。

您希望数组的内容是可变的还是包含它的变量?如果你想要可变内容,这对你有用吗?

let state = [mut [mut 0u8, ..4], ..4];

如果您希望变量是可变的而不是内容,请尝试:

let mut state = [[0u8, ..4], ..4];

这有帮助吗?我实际上没有编译它,所以语法可能稍微偏离。

答案 3 :(得分:3)

初始化:
二维数组初始化有几种方法:

  1. 使用M(行)和N(列)的常量

    const M: usize = 2;
    const N: usize = 4;
    
    let mut grid = [[0 as u8; N] ; M];
    
  2. 带有类型注释的显式声明

    let mut grid: [[u8; 4]; 2] = [[0; 4]; 2];
    

遍历:
只读遍历非常简单:

for (i, row) in grid.iter().enumerate() {
    for (j, col) in row.iter().enumerate() {
        print!("{}", col);
    }
    println!()
}

for el in grid.iter().flat_map(|r| r.iter()) {
    println!("{}", el);
}

更新元素:

for (i, row) in grid.iter_mut().enumerate() {
    for (j, col) in row.iter_mut().enumerate() {
        col = 1;
    }
}

答案 4 :(得分:3)

如果您愿意安装板条箱,ndarray可以为您提供优雅的解决方案。

use ndarray::Array2;
let mut array = Array2::zeros((4, 3));
array[[1, 1]] = 7;

有了一些已经存在的答案,就不可能使用非恒定维创建数组。 ndarray没有此类问题。您也可以毫不费力地创建两个以上的尺寸。

您可以找到更多详细信息herehere

答案 5 :(得分:2)

使用与访问数组时相同的数组大小顺序声明惯用C二维数组:

// Declaration
int array_2d[8][16]; // An 8 by 16 2D array
...
// Access
array_2d[0][1] = 5;

在Rust中,声明大小被翻转;要创建一个8乘16的二维数组,语法为:

// Declaration
let mut array_2d: [[i32; 16]; 8];
...
// Access (same as idiomatic C. types for added explicitness)
array_2d[0_usize][1_usize] = 5;

答案 6 :(得分:1)

如果您在编译时没有已知的大小,也可以创建这样的2D数组(使用Vec

let width = 4;
let height = 4;

let mut array = vec![vec![0; width]; height];

像这样使用它:

array[2][2] = 5;

println!("{:?}", array);

输出:

  

0 0 0 0
  0 0 0 0
  0 0 5 0
  0 0 0 0

自rust 1.0.0 https://doc.rust-lang.org/std/vec/struct.Vec.html

起可用

答案 7 :(得分:1)

上面已正确解决了如何创建矢量的问题,这里是创建2d矢量然后用用户输入填充的代码段

use std::io;

fn main(){

    let width = 4;
    let height = 4;
    
    let mut array = vec![vec![0; width]; height];

    for i in 0..4 { 
        let mut xstr = String::from("");
        io::stdin().read_line(&mut xstr).ok().expect("read error");
        array[i] = xstr.split_whitespace().map(|s| s.parse().expect("parse error")).collect();
    }

    println!("{:?}",array)

}

答案 8 :(得分:1)

二维字符串数组的另一个示例:

fn main() {
    let width = 2;
    let height = 3;

    let mut a: Vec<Vec<String>> = vec![vec![String::from(""); width]; height];

    for i in 0..height {
        for j in 0..width {
            let s = format!("{}:{}", i + 1, j + 1);
            a[i][j] = s;
        }
    }
    println!("{:?}", a);
}

输出:

[
  ["1:1", "1:2"], 
  ["2:1", "2:2"], 
  ["3:1", "3:2"]
]

但不确定为什么不能使用以下形式:a = [[String::from(""), 2], 3] 不了解vec![][]之间的区别

答案 9 :(得分:0)

显式初始化

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

具有相同的值

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