2015-12-02 2 views
1

я не могу получить этот код, чтобы скомпилировать:«несоответствие типов» в то время как цикл над 2D массива

fn main() { 
    let grid: [[Option<i32>;2];2] = [ 
    [Some(1),Some(2)], 
    [None,Some(4)], 
    ]; 

    for row in grid.iter() { 
    for v in row.iter() { 
     match v { 
     Some(x) => print!("{}", x), 
     None => print!(" "), 
     } 
    } 
    print!("\n"); 
    } 
} 

Я получаю сообщение об ошибке

Compiling array-2d v0.1.0 (file:///Users/paul/src/test/rust/array-2d) 
src/main.rs:8:5: 13:6 error: type mismatch resolving `<core::slice::Iter<'_, core::option::Option<i32>> as core::iter::Iterator>::Item == core::option::Option<_>`: 
expected &-ptr, 
    found enum `core::option::Option` [E0271] 
src/main.rs: 8  for v in row.iter() { 
src/main.rs: 9  match v { 
src/main.rs:10   Some(x) => print!("{}", x), 
src/main.rs:11   None => print!(" "), 
src/main.rs:12  } 
src/main.rs:13  } 
src/main.rs:8:5: 13:6 note: in this expansion of for loop expansion 
src/main.rs:7:3: 15:4 note: in this expansion of for loop expansion 
src/main.rs:8:5: 13:6 help: run `rustc --explain E0271` to see a detailed explanation 
error: aborting due to previous error 
Could not compile `array-2d`. 

Может кто-то интерпретировать, что сказать мне, что Я поступаю неправильно?

+0

Обратите внимание, что стиль ржавчины - это 4-х сторонние отступы. Кроме того, аннотация типа не требуется, пробелы появляются после запятых, и вы обычно видите 'for x in & collection'. [Пример] (http://is.gd/NnGUDw). – Shepmaster

+0

Можете ли вы объяснить, почему 'for row in & grid' позволяет мне оставить символ' .iter() '? –

+0

Убедитесь, что вы знакомы с разделами [* Язык программирования ржавчины *] (http://doc.rust-lang.org/stable/book) в [итераторах] (http://doc.rust-lang.org/ stable/book/iterators.html) и [петли] (http://doc.rust-lang.org/stable/book/loops.html). Недостающая часть состоит в том, что выражение цикла for for должно соответствовать ['IntoIterator'] (https://doc.rust-lang.org/std/iter/trait.IntoIterator.html), которое автоматически вызывается. Вы заметите, что «IntoIterator» реализован для ссылок на массивы и срезы. – Shepmaster

ответ

1

Простой. Вам просто не хватает, что ссылка v.

pub fn main() { 
    let grid: [[Option<i32>;2];2] = [ 
    [Some(1),Some(2)], 
    [None,Some(4)], 
    ]; 

    for row in grid.iter() { 
    for &v in row.iter() { 
     match v { 
     Some(x) => print!("{}", x), 
     None => print!(" "), 
     } 
    } 
    print!("\n"); 
    } 

    // Keep in mind that i32 is Copy (but Option is not) 
    // and an Array of X is Copy if X is Copy, 
    // So there is no need to borrow v here, as follows: 
    let grid2: [[i32;2];2] = [ 
    [1,2], 
    [0,4], 
    ]; 

    for row in grid2.iter() { 
    for v in row.iter() { 
     print!("{}", v); 
    } 
    print!("\n"); 
    } 
} 
+0

Спасибо! Итак, следующий вопрос: я не могу сказать 'для строки в сетке' (нет' .iter() '), но я * могу * сказать' for & v in row'. Почему '.iter()' необязательный во второй строке, но не первый? –

+0

Поскольку вы можете скопировать массив, а не ссылаться на него, если в содержимом массива также реализована копия. i32 реализует Copy, но необязательно нет, поэтому вы можете скопировать файл [i32; 2] без дополнительного синтаксиса, но не [Необязательный ; 2]. – SeanTater

+0

Я говорю о внутреннем цикле в исходном коде (с опцией «Необязательно»). Почему '.iter()' требуется для внешнего цикла, но не для внутреннего цикла? Я думаю, @Shepmaster ответил на это выше, сказав, что «IntoIterator» реализуется ссылками на массивы, но не массивами. Правильно ли это звучит? –

Смежные вопросы