Std :: fs :: File + documentation + try it! = E0308

I want to create an empty file, so I took an example and I used nightly build today

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

fn main() {
    let mut f = try!(File::create("foo"));
}

      

Startup rustc

has errors:

<std macros>:5:8: 6:42 error: mismatched types:
 expected `()`,
    found `core::result::Result<_, _>`
(expected (),
    found enum `core::result::Result`) [E0308]
<std macros>:5 return $ crate:: result:: Result:: Err (
<std macros>:6 $ crate:: convert:: From:: from ( err ) ) } } )
<std macros>:1:1: 6:48 note: in expansion of try!
file_io.rs:5:17: 5:42 note: expansion site
<std macros>:5:8: 6:42 help: pass `--explain E0308` to see a detailed explanation
error: aborting due to previous error

      

If I uninstall try!

it compiles, but how should I handle errors? And why isn't the example compiled like?

+3


source to share


2 answers


try!

is a macro to be used in functions that return Result

. Therefore it cannot be used in a function main

, because it returns one (empty tuple).

See how it expands:



fn main() {
    let mut f = match File::create("foo") {
        Ok(val) => val,
        Err(err) => return Err(From::from(err)),
    };
}

      

http://blog.burntsushi.net/rust-error-handling/ - good article on error handling in Rust for simple scripts like yours, using Result::unwrap

( File::create("foo").unwrap()

) is probably sane.

+4


source


Let's look at the macro try!()

:

macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            return $crate::result::Result::Err($crate::convert::From::from(err))
        }
    })
}

      

As you can see, either try!()

gives val

as an expression or returns Err

from a function. Therefore, after processing the macro, the expanded code looks like this:



fn main() {
    let mut f = (match File::create("foo") {
        Ok(val) => val,
        Err(err) => {
            return Err(...)
        }
    })
}

      

Hopefully the error is now obvious: main()

should return ()

, but you return Err

(which is of type Result<File>

).

The moral of the story is that you are using try!()

the wrong script. It should only be used in a function that is already intended to return Result

, just as you would throw (obscure) an exception in C ++ or Java. In your case, however, you need to explicitly refer to the error - there are no bubbles there. A possible solution, although not very elegant, is to use .unwrap()

the program to crash in case Err

.

+3


source







All Articles