如何为向量的迭代器元素的Into添加类型注释?

时间:2018-10-22 15:58:42

标签: vector rust annotations traits

我有一个向量,该向量的值已定义为特征,并且我想在此向量上使用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`

在这种情况下,我应该在哪里放置类型注释,什么是预期的类型注释?

playground

2 个答案:

答案 0 :(得分:2)

一种可能性是通知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());
    }
}

答案 1 :(得分:0)

我不知道您的确切用例是什么,但我通常会假设Into<u32>的类型可以被克隆并且克隆成本低,所以我认为最简单的解决方案是

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

这将在调用每个元素之前.into()克隆每个元素,这将消耗克隆。

请注意,我已将参数s更改为切片。如果您仍然通过按值来使用向量来使用向量,那么使用第一个示例中的代码不会有任何危害,因此仅当按引用进行切片时才有意义。