解答

// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {
    let mut result = [[0; 3]; 3];
    for i in 0..3 {
        for j in 0..3 {
            result[j][i] = matrix[i][j];
        }
    }
    result
}

fn main() {
    let matrix = [
        [101, 102, 103], // <-- the comment makes rustfmt add a newline
        [201, 202, 203],
        [301, 302, 303],
    ];

    println!("Original:");
    for row in matrix {
        println!("{row:?}");
    }

    let transposed = transpose(matrix);

    println!("\nTransposed:");
    for row in transposed {
        println!("{row:?}");
    }
}
  • 配列型:[[i32; 3]; 3] は、サイズ 3 の配列を表し、 各要素自体が 3 個の i32 からなる配列です。これは、多次元 配列を Rust で通常表現する方法です。
  • 初期化: result は、値を埋める前にゼロ ([[0; 3]; 3]) で 初期化します。Rust では、すべての変数は使用前に初期化されている 必要があり、安全な Rust には「未初期化メモリ」という概念は ありません。
  • Copy セマンティクス: Copy 型 (i32 など) の配列自体も Copy です。 matrix を関数に渡すと、値渡しによってコピーされます。変数 result は、新しい別個の配列です。
  • 反復: 標準的な範囲 (0..3) を使った for ループで、添字を反復 処理します。Rust には強力なイテレータもあり、それらは後で見ますが、 この行列の転置ではインデックス指定が分かりやすいやり方です。
  • [i32; 3][i32; 4] とは別の型であることに触れてください。配列のサイズは 型シグネチャの一部です。
  • 学生に、matrix を変更した後にそれを直接返そうとするとどうなるか(シグネチャを mut matrix に変更した場合)を尋ねてください。(答え: 動作しますが、返されるのは 変更された コピー であり、main 内の元の値は変更されません。)