rust - 实现迭代器的另一个特性

标签 rust iterator traits

我正在尝试向所有Iterator添加另一个特征。但是我不明白为什么它不能编译。
这是代码:

use std::fmt::Display;
use std::iter::Sum;

trait Topla<T> {
    fn topla(&mut self)-> T;
}

impl<T, I> Topla<T> for I
where
    T: Sum + Display,
    I: Iterator<Item = T>,
{
    fn topla(&mut self) -> T {
        self.sum()
    }
}

fn main() {
    let data = vec![1,2,3,5,8];
    println!("{:?}", data.iter().topla());
}

最佳答案

如果我们使用完全限定的trait语法,则问题会自行解决:

fn main() {
    let data = vec![1,2,3,5,8u32];
    let mut iter = data.iter();
    println!("{:?}", Topla::<u32>::topla(&mut iter));
}
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, u32> as std::iter::Iterator>::Item == u32`
  --> src/main.rs:22:22
   |
5  |     fn topla(&mut self) -> T;
   |     ------------------------- required by `Topla::topla`
...
22 |     println!("{:?}", Topla::<u32>::topla(&mut iter));
   |                      ^^^^^^^^^^^^^^^^^^^ expected reference, found `u32`
   |
   = note: expected reference `&u32`
                   found type `u32`
   = note: required because of the requirements on the impl of `Topla<u32>` for `std::slice::Iter<'_, u32>`
Topla<u32>更改为Topla<&u32>使我们更加接近:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `&u32: std::iter::Sum` is not satisfied
  --> src/main.rs:22:22
   |
5  |     fn topla(&mut self) -> T;
   |     ------------------------- required by `Topla::topla`
...
22 |     println!("{:?}", Topla::<&u32>::topla(&mut iter));
   |                      ^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Sum` is not implemented for `&u32`
   |
   = help: the following implementations were found:
             <u32 as std::iter::Sum<&'a u32>>
             <u32 as std::iter::Sum>
   = note: required because of the requirements on the impl of `Topla<&u32>` for `std::slice::Iter<'_, u32>`
问题是没有为Sum<&u32>实现&u32;它是针对u32实现的。由于我们需要返回一个u32而不是&u32,因此我们需要放宽对T的要求,从本身是迭代器类型变为仅具有T的Sum
trait Topla<T> {
    fn topla(&mut self) -> T;
}

impl<T, I> Topla<T> for I
where
    T: Display + Sum<<I as Iterator>::Item>,
    I: Iterator,
{
    fn topla(&mut self) -> T {
        self.sum()
    }
}

fn main() {
    let data = vec![1,2,3,5,8u32];
    let mut iter = data.iter();
    println!("{:?}", Topla::<u32>::topla(&mut iter));
}
但是现在,如果我们返回原始语法,则会遇到类型推断错误,这会使我们的新API变得非常烦人。我们可以通过更加严格地使用API​​来解决此问题。
如果我们将Topla设为Iterator的子特征,则可以在topla方法的定义中引用项目类型,因此将输出的类型参数移至方法中而不是特征中。这将使我们像使用sum()一样使用turbofish语法。最后,我们有:
use std::fmt::Display;
use std::iter::Sum;

trait Topla: Iterator {
    fn topla<T>(self) -> T
    where
        Self: Sized,
        T: Sum<<Self as Iterator>::Item>;
}

impl<I> Topla for I
where
    I: Iterator,
    <I as Iterator>::Item: Display,
{
    fn topla<T>(self) -> T
    where
        Self: Sized,
        T: Sum<<Self as Iterator>::Item>,
    {
        self.sum()
    }
}

fn main() {
    let data = vec![1, 2, 3, 5, 8];
    println!("{:?}", data.iter().topla::<u32>());
}

关于rust - 实现迭代器的另一个特性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63526094/

相关文章:

computer-science - 装饰器,属性,方面和特质有什么区别?

rust - 如何从单行标准输入中读取多个整数?

rust - 如何避免在 Rust 的代码块内意外地重新声明变量?

rust - 如何在 Rust 中实现带量纲的标量算法?

PHP 接口(interface) IteratorAggregate vs Iterator?

c++ - 无效使用非静态数据成员 'linkedList<int>::dummyNode' c++

rust - 使用参数为本地类型实现外部特征时出现错误 E0201

struct - 实现 Rust 特征会导致找不到结构

rust - 为什么 Serde 不能为仅包含 &Path 的结构派生反序列化?

c++ - 随机遍历 map 会导致段错误