gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:47:56 24 4
gpt4 key购买 nike

我正在尝试向所有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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com