Как добавить аннотации типов для Into для элемента итератора вектора? - PullRequest
0 голосов
/ 22 октября 2018

У меня есть вектор, значения которого определены чертой, и я хотел бы использовать методы, предусмотренные чертой Iterator для этого вектора.

Вот упрощенный код моего варианта использования:

Вариант A

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

Вариант B

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

Вариант A действителен, компилируется и работает, как ожидается. Случай B , однако, вызовет ошибку времени компиляции:

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

Где мне разместить аннотацию типа в этом случае и какова ожидаемая аннотация типа?

детская площадка

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Я не знаю, какой у вас точный вариант использования, но я бы предположил, что типы, которые Into<u32>, могут быть клонированы и дешевы для клонирования, поэтому я думаю, что самое простое решение -

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

Это будет клонировать каждый элемент перед вызовом .into() для него, который будет использовать клон.

Обратите внимание, что я изменил аргумент s на фрагмент.Если вы все равно потребляете вектор, беря его по значению, использование кода из первого примера не повредит, поэтому это имеет смысл, только если вы берете фрагмент по ссылке.

0 голосов
/ 22 октября 2018

Одной из возможностей было бы сообщить beta2, что &U (в отличие от U) реализует Into<i32>:

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

Обратите внимание, что Into принимает self, а не &self, то есть он потребляет свой аргумент.Таким образом, вам нужно будет найти способ конвертировать заемный x в собственную стоимость:

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());
    }
}
...