2016-11-13 6 views
0

Вдохновленный кодом, указанным evilone в сообщении How to print a Vec?. Чтобы отобразить матрицу, я написал код следующим образом:Несоответствующие типы при отображении матрицы с петлей для петли

use std::{ops, fmt}; 

#[derive(PartialEq, Debug)] 
pub struct Matrix<T> { 
    data: Vec<T>, 
    row: usize, 
    col: usize, 
} 

impl<T: Copy> Matrix<T> {  
    pub fn new(row: usize, col: usize, values: &[T]) -> Matrix<T> { 
     Matrix { 
      data: values.to_vec(), 
      row: row, 
      col: col, 
     } 
    } 
}  

//// Display 
impl<T: fmt::Display> fmt::Display for Matrix<T> { 

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     let n_row = self.row; 
     let n_col = self.col; 
     let data = self.data; 

     for i in 0.. n_row { 
      let mut each_row = String::new(); 

      for j in 0.. n_col { 
       let idx = i * n_col + j; 
       let each_element = data[idx]; 
       each_row.push_str(&each_element.to_string()); 
       each_row.push_str(" "); // seperated by space 
      } 
      write!(f, "{}", each_row) 
     } 
    } 
}  

fn main() { 
    let x = Matrix::new(2, 3, &[-6, -5, 0, 1, 2, 3]); 
    println!("{}", x); 

} 

Я получил ошибку:

rustc 1.13.0 (2c6933acc 2016-11-07) 
error[E0308]: mismatched types 
    --> <anon>:40:13 
    | 
40 |    write!(f, "{}", each_row) 
    |    ^^^^^^^^^^^^^^^^^^^^^^^^^ expected(), found enum `std::result::Result` 
    | 
    = note: expected type `()` 
    = note: found type `std::result::Result<(), std::fmt::Error>` 
    = note: this error originates in a macro outside of the current crate 

error[E0308]: mismatched types 
    --> <anon>:31:9 
    | 
31 |   for i in 0.. n_row { 
    |  ^expected enum `std::result::Result`, found() 
    | 
    = note: expected type `std::result::Result<(), std::fmt::Error>` 
    = note: found type `()` 

1) Я не понимаю, почему я получаю expected(), found enum `std::result::Result`

2) Для второго ошибка, я думал, что это было вызвано неспособностью реализовать строку 40. Так что если строка исправления 40, это больше не будет проблемой.

Любые предложения по исправлению этого вопроса?

ответ

2

При программировании полезно создать Minimal, Complete, and Verifiable Example. Это означает, что вы удаляете все, что не имеет отношения к ошибке или проблеме, с которой вы сталкиваетесь, кипятите ее до чистой сути. Как правило, вы обнаружите, что это значительно сужает потенциальное местоположение проблемы. Часто это позволяет вам самому ответить на вопрос, а в других случаях увеличивает шансы на то, чтобы задать проницательный вопрос.

Вот MCVE этой проблемы:

fn foo() -> u8 { 
    for i in 0..1u8 { 
     i 
    } 
} 

fn main() {} 

Довольно мало, не так ли? Он производит эти ошибки:

error[E0308]: mismatched types 
--> src/main.rs:3:9 
    | 
3 |   i 
    |  ^expected(), found u8 
    | 
    = note: expected type `()` 
    = note: found type `u8` 

error[E0308]: mismatched types 
--> src/main.rs:2:5 
    | 
2 |  for i in 0..1u8 { 
    | ^expected u8, found() 
    | 
    = note: expected type `u8` 
    = note: found type `()` 

Который должен выглядеть знакомым.

Теперь задайте себе вопрос: какой тип и значение делает цикл for? (Подсказка: сообщения компилятора на самом деле сказать вам, если вы читаете их правильный путь)

Мы знаем, что функция должна возвращать u8, но компилятор говорит нам, что мы на самом деле возвращая () - это второй ошибка. Это означает, что цикл for оценивается до ()! Поскольку цикл for оценивается как (), что может произойти со значением, которое оценивает блок цикла for? Как вы можете догадаться, ответ заключается в том, что блок не может вернуть значение!

Подумайте о этого примера:

fn foo() -> u8 { 
    for i in 0..0u8 { 
     // 
    } 
} 

Что бы это возвращения? Да, наверное, ничего хорошего.


Возвращаясь из нашего MCVE обратно к исходной задаче, вы должны явно возвращать внутренние неудачи и явно возвращать успех в конце цикла:

for /* ... */ { 
    // ... 

    try!(write!(f, "{}", each_row)) 
} 

Ok(()) 

Это просто открывает дверь в другие ошибки в коде, но вы способны понять их!

+0

Большое спасибо за руководство, чтобы увидеть суть. Я полностью согласен, что я должен научиться глубоко заглядывать в отчеты об ошибках и делать дело MCVE.В эти дни я борется и многому учусь в Rust. – enaJ

+1

@enaJ угнаться тяжелую работу! Создание сокращенного случая, повторяющего ошибку, - это то, что поможет вам на протяжении всей карьеры программирования. – Shepmaster

+0

Определенно! Я пришел с фона python и начал изучать Rust 6 недель назад. Они во многом отличаются друг от друга. Но я считаю, что каждый язык помогает глубже и глубже других. – enaJ