简体   繁体   中英

How to add type annotations for Into for the iterator element of a vector?

I have a vector whose values are trait defined and I would like to use the methods provided by the Iterator trait on this vector.

Here is an simplified code of my use case:

Case A

fn beta<T: Into<i32>>(s: Vec<T>) {
    for x in s {
        println!("{:?}", x.into());
    }
}

Case B

fn beta2<U: Into<i32>>(s: Vec<U>) {
    for x in s.iter() {
        println!("{:?}", x.into());
    } 
}

Case A is valid and compiles and runs as expected. Case B however will raise a compile time error:

error[E0282]: type annotations needed
  --> src/main.rs:11:26
   |
11 |         println!("{:?}", x.into());
   |                          ^^^^^^^^ cannot infer type for `T`

Where should I place my type annotation in this case and what's the expected type annotation?

playground

One possibility would be to inform beta2 that &U (as opposed to U ) implements Into<i32> :

fn beta2<U>(s: Vec<U>)
where
    for<'a> &'a U: Into<i32>,
{
    for x in s.iter() {
        println!("{:?}", x.into());
    }
}

Note that Into accepts self and not &self , ie it consumes its argument. Thus, you would have to find some way to convert the borrowed x into an owned value:

fn beta2<U, U2>(s: Vec<U>)
where
    U: std::borrow::ToOwned<Owned = U2>,
    U2: Into<i32> + std::borrow::Borrow<U>,
{
    for x in s.iter() {
        println!("{:?}", x.to_owned().into());
    }
}

I don't know what your exact use case is, but I would generally assume that types that are Into<u32> can be cloned and are cheap to clone, so I think the easiest solution is

fn beta2<U: Clone + Into<i32>>(s: &[U]) {
    for x in s.iter().cloned() {
        println!("{:?}", x.into());
    }
}

This will clone each element before calling .into() on it, which will consume the clone.

Note that I have changed the argument s to a slice. If you are consuming the vector anyway by taking it by value, there is no harm in using the code from your first example, so this only makes sense if you take a slice by reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM