Parsing text file lines into numbers using std::iter::Iterator map -
i'm trying read , parse text file in rust. each line signed integer. i'm able using for line in lines
iteration i'm unable iter().map(|l| ...)
one-liner. i'm getting a
expected `&core::result::result<collections::string::string, std::io::error::error>`, found `core::result::result<_, _>`
when try pattern match ok(s) => match s.parse()
i'm unable bottom of doing wrong. whole example below. code on bottom code producing error.
can tell doing wrong?
use std::error::error; use std::fs::file; use std::io::bufreader; use std::io::prelude::*; use std::path::path; fn main() { // create path desired file let path = path::new("input/numbers.txt"); let display = path.display(); // open path in read-only mode, returns `io::result<file>` let file = match file::open(&path) { // `description` method of `io::error` returns string describes error err(why) => panic!("couldn't open {}: {}", display, error::description(&why)), ok(file) => file, }; // collect lines vector let reader = bufreader::new(file); let lines: vec<_> = reader.lines().collect(); // works. let mut nums = vec![]; l in lines { println!("{:?}", l); let num = match l { ok(s) => match s.parse() { ok(i) => i, err(_) => 0 }, err(_) => 0 }; nums.push(num); } // doesn't work! let nums: vec<i64> = lines.iter().map(|l| match l { ok(s) => match s.parse() { ok(i) => i, err(_) => 0 }, err(_) => 0 }); }
let's @ complete error message, points error us:
<anon>:5:9: 5:14 error: mismatched types: expected `&core::result::result<&str, ()>`, found `core::result::result<_, _>` (expected &-ptr, found enum `core::result::result`) [e0308] <anon>:5 ok(s) => match s.parse() { ^~~~~
the compiler expecting &result
, found result
, , issue ok(s)
pattern. type of l
reference result
because using iter
- returns an iterator of references items in vector.
the shortest fix add &
pattern match closure variable:
fn main() { let lines: vec<result<_, ()>> = vec![ok("1"), ok("3"), ok("5")]; // here v let nums: vec<i64> = lines.iter().map(|&l| match l { ok(s) => match s.parse() { ok(i) => i, err(_) => 0 }, err(_) => 0 }).collect(); println!("{:?}", nums) }
i had add collect
go vec
.
the other change make consume input vector using into_iter
, iterate on each value in vector:
// here v~~~~ let nums: vec<i64> = lines.into_iter().map(|l| match l {
and measure, use ok
, and_then
, , unwrap_or
same thing bit more succinctly:
let nums: vec<i64> = lines.into_iter().map(|l| { l.ok().and_then(|s| s.parse().ok()).unwrap_or(0) }).collect();
Comments
Post a Comment