Продолжаю изучать Rust и вот решил попробовать в нём массивы.
Массивы в Rust неитерабельные, тоесть нельзя написать for item in array {...}. Вместо этого придётся написать либо for item in &array {...} либо for item in array.iter() {...} либо for item in array.to_vec() {...} либо что-то другое похожее, что создаёт из массива объект итерабельного типа. Ну или использовать цикл, который бежит по индексам for i in 0..array.len() { let n = array[i]; ...}. По моему это недостаток Rust. Для примера в Java for-each неявно разворачивается в одну из двух версий: с использованием индекса или с использованием итератора - в зависимости от того массив ли это или Iterable. Rust умеет делать лишь второй вариант, хотя это такой же синтаксический сахар, как и for-each в Java.
Так же, на сколько я понял, массив в Rust является не объектом, как в Java, а просто куском памяти с обвесами из макросов, как в C/C++. Таким образом функция не может получить, в качестве параметра, массив, длина которого неизвестна во время компиляции. Следующие три варианта функции не скомпилируются с тремя разными сообщениями об ошибке:
fn print_array1(array: [i32]) {
    //
}
fn print_array2(array: [i32; n], n: i32) {
    //
}
fn print_array3(n: i32, array: [i32; n]) {
    //
}Варианты вроде
fn print_array(array: [i32; 27]) {...} работать будут, но практической пользы не имеют. Значит придётся передавать не массив, а созданный из него итерабельный объект. Но это приводит к накладным расходам и с точки зрения системного программирования выглядит не очень хорошо. Может быть это ограничение снято в unsafe?Ну хорошо, пусть речь идёт не о системном, а о прикладном программировании. Предположим, что я хочу пройтись по всем элементам двумерного массива, например, чтобы распечатать его в виде таблицы. В этом случае удобнее сразу пользоваться не массивом, а скажем слайсом (срезом), более похожим на массив в Java. В итоге у меня получился следующий код:
fn main() {
    let desk: &[&[i32]] = &[&[1, 2, 3, 4], &[5, 6, 7, 8], &[9, 10, 11, 12], &[13, 14, 15, 16]];
    print_desk(desk)
}
fn print_desk(desk: &[&[i32]]) {
    for line in desk {
        for cell in *line {
            print!("{:02} ", cell)
        }
        println!()
    }
}
Здесь у меня возникла проблема во внутреннем цикле. Я полагал, что типом переменной
line является &[i32], но оказалост, что он &&[i32]. Поэтому во внутреннем цикле пришлось бежать не по line, а по *line. Другими вариантами были line.iter() или line.to_vec(). Почему здесь такой неконсистентный синтаксис? Так же, почему в сообщении об ошибке предлагается использовать более накладный line.iter() а не *line?





