Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Решение

// 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], // <-- rustfmt сохранит перенос на следующую строку
        [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 (например, i32) сами являются Copy. Когда мы передаём matrix в функцию, она копируется по значению. Переменная result — новый отдельный массив.
  • Итерация: мы используем обычные циклы for с диапазонами (0..3), чтобы перебрать индексы. В Rust есть и мощные итераторы, которые мы рассмотрим позже, но для транспонирования матрицы индексация достаточно проста.
  • Отметьте, что [i32; 3] — это другой тип, чем [i32; 4]. Размеры массивов входят в сигнатуру типа.
  • Спросите студентов, что произойдёт, если они попытаются вернуть matrix напрямую после изменения (если поменяли сигнатуру на mut matrix). (Ответ: это сработает, но вернётся изменённая копия, а исходный массив в main останется без изменений.)