繁体   English   中英

如何在Rust中编写一个函数,该函数接受Item满足特征的任何迭代器?

[英]How do I write a function in Rust that accepts any iterator whose Item fulfills a trait?

这是我想要达到的目标的人为示例:

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

错误在这里显示为“期望的积分变量,找到&Double ”。

我到处都在寻找麻烦,因为到处都在谈论迭代器是特质。 我要做什么甚至有可能吗?

是的,有可能。 您需要使用where子句来指定关联类型I::Item的绑定。

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

(我还将I: Iterator绑定到where子句,以使所有边界保持在一起。)

绑定的Iterator<Item = &'a Double>>表示您想要一个迭代器,该迭代器产生的类型&Double完全相同,该类型表示特性Double的特性对象。 但是,您需要一个迭代器,该迭代器可以产生实现特征Double任何类型。 这听起来很相似,因此令人困惑,但这全是关于动态与静态分派。 您应该阅读有关特质对象的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());
    }
}

但是您也可以绑定迭代器的关联类型(请参见FrancisGagné的答案 ):

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

但是,这两个版本略有不同,因为一个版本接受对实现Double类型的引用的迭代器,而另一个版本对直接实现Double类型的迭代进行迭代。 只需使用最适合您的方法或使用AsRef特征概括这两件事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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