rust - Why do try!() and ? not compile when used in main? -


why code not compile?

use std::io; use std::fs; use std::path::path;  fn main() {     // open path     let dir = path::new("../filesystem");      // check if directory     if !dir.is_dir() {         println!("is not directory");         return;     }      item in try!(fs::read_dir(dir)) {         let file = match item {             err(e) => {                 println!("error: {}", e);                 return;             }             ok(f) => f,         };          println!("");     }      println!("done"); } 

this error get

error[e0308]: mismatched types   --> src/main.rs:15:17    | 15 |     item in try!(fs::read_dir(dir)) {    |                 ^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::result`    |    = note: expected type `()`               found type `std::result::result<_, _>`    = help: here functions might fulfill needs:            - .unwrap()            - .unwrap_err()            - .unwrap_or_default()    = note: error originates in macro outside of current crate 

i think complaining line: for item in try!(fs::read_dir(dir))

i tried question mark operator:

for item in fs::read_dir(dir)? { 

which had different error:

error[e0277]: trait bound `(): std::ops::try` not satisfied   --> src/main.rs:15:17    | 15 |     item in fs::read_dir(dir)? {    |                 ------------------    |                 |    |                 trait `std::ops::try` not implemented `()`    |                 in macro invocation    |    = note: required `std::ops::try::from_error` 

previous versions of rust had similar error std::ops::carrier

should avoid try!() , ?? best way handle errors? this:

match error_prone {     err(e) => {         println!("error: {}", e);         return;     },     ok(f) => f, }; 

but if have use in loop, it's complete mess

for in match error_prone {     // match code } {     // loop code } 

try! macro returns errs automatically; ? syntax same thing. both can used in functions return result (until rfc 1859 implemented). main doesn't return value (until rfc 1937 implemented).

this how might transform code use ?:

use std::error::error; use std::fs; use std::path::path;  fn print_dir_contents() -> result<string, box<error>> {     // open path     let dir = path::new("../filesystem");      // check if directory     if !dir.is_dir() {         return err(box::from("is not directory!"));     }      entry in fs::read_dir(dir)? {         let path = entry?.path();         let file_name = path.file_name().unwrap();         println!("{}", file_name.to_string_lossy());     }      ok("done".into()) }  fn main() {     match print_dir_contents() {         ok(s) => println!("{}", s),         err(e) => println!("error: {}", e.to_string()),     } } 

there's lot of error handling here might not expect - other languages don't tend require it! exist in other languages - rust makes know it. here errors:

entry? 

io errors can happen during iteration.

path.file_name().unwrap() 

not paths have file names. can unwrap because read_dir won't give path without file name.

file_name.to_string_lossy() 

you can to_str , throw error, it's nicer this. error exists because not file names valid unicode.

try! , ? throw errors return value, converting them box::error. it's more reasonable return amalgamated error of things can go wrong. luckily io::error right type:

use std::io; ... fn print_dir_contents() -> result<string, io::error> {     ...     if !dir.is_dir() {         return err(io::error::new(io::errorkind::other, "is not directory!"));     }     ... } 

frankly, though, check in fs::read_dir, can remove if !dis.is_dir altogether:

use std::io; use std::fs; use std::path::path;  fn print_dir_contents() -> result<string, io::error> {     // open path     let dir = path::new("../filesystem");      entry in fs::read_dir(dir)? {         let path = entry?.path();         let file_name = path.file_name().unwrap();         println!("{}", file_name.to_string_lossy());     }      ok("done".into()) }  fn main() {     match print_dir_contents() {         ok(s) => println!("{}", s),         err(e) => println!("error: {}", e.to_string()),     } } 

Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -