web-dev-qa-db-fra.com

Création de tableaux bidimensionnels dans Rust

Comment créer un tableau bidimensionnel mutable vide dans Rust?

Voici ce que j'ai essayé jusqu'à présent:

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

Cela produit l'erreur

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

Note de l'éditeur: Cette réponse est antérieure à Rust 1.0 et certains concepts et syntaxe ont changé. D'autres réponses s'appliquent à Rust 1.0.

Voulez-vous que le contenu du tableau soit modifiable ou la variable qui le contient? Si vous voulez un contenu modifiable, cela fonctionne-t-il pour vous?

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

Si vous voulez que la variable soit modifiable mais pas le contenu, essayez ceci:

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

Est-ce que cela aide? Je n'ai pas vraiment compilé cela, donc la syntaxe peut être légèrement décalée.

9
Eric Holk

Dans Rust 1.0, ce qui suit fonctionne:

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

Notez que la longueur du segment intérieur fait partie intégrante du type. Par exemple, vous pouvez référencer (et transmettre) state comme suit:

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

mais pas sans spécifier la longueur fixe du sous-tableau. Si vous avez besoin de sous-tableaux de longueur variable, vous devrez peut-être faire quelque chose comme ceci:

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

Vous pouvez créer un vecteur 2D de taille dynamique comme ceci:

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;
}
11
Procrade

Initialisation:
Il existe plusieurs approches pour l'initialisation d'un tableau 2D:

  1. Utilisation de constantes pour M (lignes) et N (colonnes)

    const M: usize = 2;
    const N: usize = 4;
    
    let mut grid = [[0 as u8; N] ; M];
    
  2. Déclaration explicite avec annotations de type

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

Traversée:
La traversée en lecture seule est aussi simple que:

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

ou

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

Mise à jour des éléments:

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

Les tableaux bidimensionnels idiomatiques C sont déclarés en utilisant le même ordre de tailles de tableau que celui utilisé lors de l'accès au tableau:

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

En rouille, les tailles de déclaration sont inversées; pour créer un tableau bidimensionnel de 8 x 16, la syntaxe est la suivante:

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