Jkjk
Jkjk

Reputation: 37

Partition over Vec<Result<T, E>> fails due to type mismatch

I'm attempting to collect a series of calculations which can fail into two vectors, one containing the successful calculations and one containing any errors.

I can instantiate the vector Vec<Result<T, E>> but calling partition fails to compile.

Example code:

fn main() {
    let f:Result<i32, String> = Err("a".to_owned());
    let s:Result<i32, String> = Ok(5);
    let v:Vec<Result<i32, String>> = vec![f, s];
    
    // works
    dbg!(&v[0]);
    dbg!(&v[1]);
    
    // fails
    let (sp, fp):(Vec<_>, Vec<_>) = v.iter().partition(Result::is_ok);
    dbg!(sp);
    dbg!(fp);
}

Error below:

error[E0631]: type mismatch in function arguments
  --> src/main.rs:12:56
   |
12 |     let (sp, fp):(Vec<_>, Vec<_>) = v.iter().partition(Result::is_ok);
   |                                              --------- ^^^^^^^^^^^^^
   |                                              |         |
   |                                              |         expected signature of `for<'r> fn(&'r &Result<i32, String>) -> _`
   |                                              |         found signature of `for<'r> fn(&'r Result<_, _>) -> _`
   |                                              required by a bound introduced by this call

Based on the rust by example docs this seems like it should be doable - what am I missing?

Upvotes: 2

Views: 227

Answers (1)

Chayim Friedman
Chayim Friedman

Reputation: 71370

iter() returns an iterator over references, and partition() takes a callback that takes a reference - that's two references. Result::is_ok(), however, takes &self with one reference.

You can either use into_iter() or provide a closure that takes two references: .partition(|result| result.is_ok()).

Upvotes: 2

Related Questions