generics - 我如何在 Rust 中编写一个函数来接受其 Item 满足特征的任何迭代器?

标签 generics rust traits

这是我想要实现的人为示例:

trait Double {
    fn get(&self) -> i32;
}

impl Double for i32 {
    fn get(&self) -> i32 { self * 2 }
}

fn foo<'a, I: Iterator<Item = &'a Double>>(is: I) {
    for i in is {
        println!("{}", i.get());
    }
}

fn main() {
    let is = vec![1, 2, 3, 4];
    foo(is.into_iter());
}

这里的错误是“expected integral variable, found &Double”。

我在谷歌搜索时遇到了麻烦,因为到处都在谈论迭代器作为特征。我尝试做的事情是否可行?

最佳答案

Iterator<Item = &'a Double>>说你想要一个迭代器,它产生完全类型为 &Double 的项目表示特征的特征对象 Double .但是你想要一个迭代器来产生任何实现特征 Double 的类型.这听起来非常相似,因此令人困惑,但这都是关于动态与静态调度的。您应该阅读有关 trait objects 的 Rust 书籍章节了解到底发生了什么。

但快速总结:写作之间存在差异

fn foo<T: MyTrait>(t: &T) {}

fn foo(t: &MyTrait) {}

你写的代码等同于后者,但实际上想要前者。


那么如何在代码中表达你的意图呢?一种可能是引入另一种类型参数!

fn foo<'a, T, I>(is: I) 
    where T: Double,
          I: Iterator<Item = &'a T>,
{
    for i in is {
        println!("{}", i.get());
    }
}

但您也可以只绑定(bind)关联的迭代器类型(参见 Francis Gagné's answer ):

fn foo<I>(is: I) 
    where I: Iterator,
          I::Item: Double,
{ ... }

但是,这两个版本略有不同,因为一个版本接受对实现 Double 类型的引用的迭代器而另一个迭代实现 Double 的类型直接地。只需使用最适合你的东西,或者用 AsRef 这样的特征来概括这两个东西.

关于generics - 我如何在 Rust 中编写一个函数来接受其 Item 满足特征的任何迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43057946/

相关文章:

rust - 为什么在具体实现中使用 Self 而不是类型名称?

scala:混合取决于参数类型

Swift 泛型无法转换返回表达式

java - 为什么我不能将 String 数组与采用 Iterable 作为参数的方法一起使用?

generics - 带有通用参数的 to_string

module - Rust 引用模块

rust - 有没有比匹配更好的方法来访问相同类型的枚举值?

rust - 如果 BufReader 取得流的所有权,我如何在其上读取和写入行?

c++ - 将模板专门化为嵌套类类型

java - 为什么 List<String> 不能作为 List<Object> 接受?