在Rust中创建二维数组

php*_*p-- 24 arrays vector multidimensional-array rust

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

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

let mut state[[u8 * 4] * 4];
Run Code Online (Sandbox Code Playgroud)

这会产生错误

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

dha*_*rdy 41

在Rust 1.0中,以下工作:

let mut state = [[0u8; 4]; 6];
state[0][1] = 42;
Run Code Online (Sandbox Code Playgroud)

请注意,内部段的长度是该类型的组成部分.例如,您可以state如下引用(和传递):

let a: &[[u8; 4]] = &state;
Run Code Online (Sandbox Code Playgroud)

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

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


Yuc*_*ong 13

Vec如果您在编译时没有已知大小,您还可以创建这样的二维数组(使用):

let width = 4;
let height = 4;

let mut array = vec![vec![0; width]; height];
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

array[2][2] = 5;

println!("{:?}", array);
Run Code Online (Sandbox Code Playgroud)

输出:

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

  • 此方法有一个问题:此代码不是创建惯用的 C 数组,而是创建指向堆中不同位置的指针(其他 Vec)的数组 (Vec)。它可能会导致某些阵列操作的性能显着下降。 (3认同)
  • @mcherm 来自上述官方文档的链接:“Vec 是并且永远是(指针、容量、长度)三元组。” 它有 N 开销,但每一行仍然可以在堆上完全不同的位置结束。 (2认同)

Pro*_*ade 12

您可以创建一个动态大小的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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为它应该读为 `...chunks_mut(height)...` 假设访问是 `grid[0...width-1][0...height-1]` (2认同)
  • 数组和向量是非常不同的东西。 (2认同)

小智 9

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

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

let state = [mut [mut 0u8, ..4], ..4];
Run Code Online (Sandbox Code Playgroud)

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

let mut state = [[0u8, ..4], ..4];
Run Code Online (Sandbox Code Playgroud)

这有帮助吗?我实际上没有编译它,所以语法可能略有偏差.

  • 您可以通过两种方式传递值.一个选项是`&mut [[u8*4]*4]`---指向二维固定长度数组的指针.你只需要`&mut state`来获得这样的指针. (3认同)
  • 哦,通常有一个像这样的可变变量也允许你改变固定长度数组的元素,因为它们由变量拥有.不幸的是,这个错误<https://github.com/mozilla/rust/issues/3226>现在会阻止你. (2认同)
  • 对于未来的访问者:这是针对1.0之前版本的生锈,下面的另一个答案是更新语法.`let mut state = [[0u8; 4]; 4];`. (2认同)

Vik*_*kar 8

如果您愿意安装板条箱,他们ndarray可以优雅地为您完成。

use ndarray::Array2;
let mut array = Array2::zeros((4, 3));
array[[1, 1]] = 7;
Run Code Online (Sandbox Code Playgroud)

对于一些已经存在的答案,不可能使用非常量维度创建数组。则不存在此类问题ndarray。您还可以轻松创建二维以上的维度。

您可以在此处此处找到更多详细信息。


Iza*_*ana 8

通过显式初始化

let directions: [[i32; 2]; 4] = [[-1, 0], [0, 1], [0, 1], [1, 0]]
Run Code Online (Sandbox Code Playgroud)

具有相同的值

let directions: [[i32; 2]; 4] = [[0; 2]; 4];
Run Code Online (Sandbox Code Playgroud)


小智 6

嗯,上面正确地解决了如何创建向量的问题。以下是创建二维向量然后用用户输入填充它的代码片段:

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)
}

Run Code Online (Sandbox Code Playgroud)


小智 5

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

// Declaration
int array_2d[8][16]; // An 8 by 16 2D array
...
// Access
array_2d[0][1] = 5;
Run Code Online (Sandbox Code Playgroud)

在 Rust 中,声明大小被翻转;要创建 8 x 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;
Run Code Online (Sandbox Code Playgroud)


mag*_*ter 5

初始化:
2D数组初始化有几种方法:

  1. 对M(行)和N(列)使用常数

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

    let mut grid: [[u8; 4]; 2] = [[0; 4]; 2];
    
    Run Code Online (Sandbox Code Playgroud)

遍历:
只读遍历是那么容易,因为:

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

要么

for el in grid.iter().flat_map(|r| r.iter()) {
    println!("{}", el);
}
Run Code Online (Sandbox Code Playgroud)

更新元素:

for (i, row) in grid.iter_mut().enumerate() {
    for (j, col) in row.iter_mut().enumerate() {
        col = 1;
    }
}
Run Code Online (Sandbox Code Playgroud)