These are chat archives for rust-lang/rust

19th
Apr 2017
Rust
@LooMaclin
Apr 19 2017 09:38
Hello everybody. I wrote an article in Russian about how to write a Telegram-bot on the rust that will compile the code with Rust playground: https://habrahabr.ru/post/326830/
I think to some it might be interesting
David Harvey-Macaulay
@alteous
Apr 19 2017 12:01

Hi, I've stumbled into a compile error whilst experimenting with iterators and I'm not sure why. The context is that I'd like to use the ? operator with Rust iterators when calling 'risky' functions.

I have lots of code that looks like this:

fn parse(strs: &[&str]) -> Result<Vec<i32>, ParseNumError> {
    let mut nums = Vec::new();
    for s in strs {
        let num = s.parse()?;
        nums.push(num);
    }
    Ok(nums)
}

Instead, I would like to be able to write this:

fn parse(strs: &[&str]) -> Result<Vec<i32>, ParseNumError> {
    strs.iter().map(|s| str::parse(s)).try_collect()
}

The above is possible, but I'm confused to why the following raises a compile error:

fn parse_and_sum(strs: &[&str]) -> Result<i32, ParseNumError> {
    strs.iter()
        .map(|s| str::parse(s))
        .try_collect::<Vec<i32>>()?
        .into_iter() // I intended this to be an `impl Iterator<Item = i32>` but is actually an `impl Iterator<Item = Result<_, _>>`
        .sum() // compiler moans here
}

Can anybody make sense of this? Playground link.

David Harvey-Macaulay
@alteous
Apr 19 2017 12:14
Also, why must I write strs.iter().map(|s| str::parse(s)) instead of strs.iter().map(str::parse)?
Denis Lisov
@tanriol
Apr 19 2017 12:24
@alteous You're trying to return i32 while the function signature requires Result<i32, ParseNumError>. If you wrap the body with Ok(...), it compiles.
David Harvey-Macaulay
@alteous
Apr 19 2017 12:34
@tanriol Thank you, that explains a lot!
Denis Lisov
@tanriol
Apr 19 2017 12:38
@alteous As for the str::parse question, note that when you write the closure expliticly, the argument s is auto-dereferenced once before calling str::parse itself.
You could do strs.iter().map(|s| *s).map(str::parse::<i32>) if preferred, but that looks more magical to me :-)
David Harvey-Macaulay
@alteous
Apr 19 2017 12:46
I'm a bit confused. It seems that calling iter() on a &[&str] returns an impl Iterator<Item = str> instead of an impl Iterator<Item = &str>. The standard library says parse() takes a slice so I'm not sure why writing the closure explicitly makes any difference.
And yeah that is a bit magical. :)
Denis Lisov
@tanriol
Apr 19 2017 12:47
Calling iter() on a &[&str] returns an impl Iterator<Item = &&str>, no?
David Harvey-Macaulay
@alteous
Apr 19 2017 12:47
Or rather, I'm not sure why calling iter() doesn't iterate over the slices.
Ah, that would explain a lot. I think I might be getting confused with the error message from the compiler.
error[E0281]: type mismatch: the type fn(&str) -> std::result::Result<_, _> {std::str::<impl str>::parse::<_>} implements the trait for<'r> std::ops::FnMut<(&'r str,)>, but the trait std::ops::FnMut<(&&str,)> is required (expected &str, found str)
--> <anon>:30:10
|
30 | .map(str::parse)
| ^^^
Denis Lisov
@tanriol
Apr 19 2017 12:49
Yeah, the error message seems to be a bit misleading... the interesting point is FnMut<(&'r str,)> vs FnMut<(&&str,)>
David Harvey-Macaulay
@alteous
Apr 19 2017 12:50
Well that clears that up then, thanks for your help! :)
Sergey Sherkunov
@leinlawun
Apr 19 2017 13:11
@LooMaclin thanks.
Rust
@LooMaclin
Apr 19 2017 13:21
@leinlawun no problem
Michal 'vorner' Vaner
@vorner
Apr 19 2017 14:43
Hello. This might seem like a strange question, but I'm looking for some material illustrating that Rust is hard to learn. I want to have a presentation in my company about why using Rust is a good idea and I want to put into contrast that despite it being hard to learn, it's the first weekend language on github, has been voted the most liked language on stack overflow (or was it reddit?).
L. Preston Sego III
@NullVoxPopuli
Apr 19 2017 17:56
does rust regex have a funny way of escaping slashes?
Error parsing regex near \'([-_\\/\\w]*\' at character offset 6:  Unrecognized escape sequence: \'\\/\'.")'
        let reg = Regex::new(r"^([-_\/\w]*)").unwrap();
vorner @vorner just got a crazy idea… with webassembly and rust support for it, did anyone try doing play.rust-lang.org in the browser?