Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mismatched types in if let statement: found Option expected Result

Tags:

rust

I am trying to parse a file that has a pipe delimiter between each value and each line is a new record. I am iterating over each line like this:

use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

fn main() {
    let source_file = File::open("input.txt").unwrap();
    let reader = BufReader::new(source_file);
    for line in reader.lines() {
        if let Some(channel_line) = line {
            println!("yay");
        }
    }
}

Playground

However, I get an error:

error[E0308]: mismatched types
  --> src/main.rs:9:20
  |
9 |             if let Some(channel_line) = line {
  |                    ^^^^^^^^^^^^^^^^^^ expected enum    `std::result::Result`, found enum `std::option::Option`
  |
  = note: expected type `std::result::Result<std::string::String, std::io::Error>`
  = note:    found type `std::option::Option<_>`

This error is confusing to me as the found type is what I expected namely Option<Result<String, Error>> as indicated by the docs so it would make sense to unwrap the Option before the result assuming I am not missing something.

like image 969
rpiper Avatar asked Oct 17 '22 23:10

rpiper


1 Answers

You linked to the documentation of next, but you're not using next (not directly anyway), you're using a for loop. In a for loop the type of the iteration variable (i.e. the type of line in your code) is the Item type of the iterator, which in your case is Result<String>.

The type of next is Option<Item> because you might call next on an iterator that already reached the end. The body of a for loop won't ever execute after the end of the iteration, so there's no point in the iteration variable being an option.

like image 200
sepp2k Avatar answered Oct 21 '22 00:10

sepp2k