我有一个特点

trait Foo<T> : Iterator<Item=T> {
    fn bar(&mut self) -> f64;
}

我想对类型T(在我的例子中是f64)在其所有引用类型(f64&'a f64&'a mut f64)上实现这个特性一次,因为从逻辑上来说,这并不重要.

我现在有

impl<T: Iterator<Item = f64>> Foo<f64> for T {
    fn bar(&mut self) -> f64 {
        // duplicated code
    }
}

impl<'a, T: Iterator<Item = &'a f64>> Foo<&'a f64> for T {
    fn bar(&mut self) -> f64 {
        // duplicated code
    }
}

impl<'a, T: Iterator<Item = &'a mut f64>> Foo<&'a mut f64> for T {
    fn bar(&mut self) -> f64 {
        // duplicated code
    }
}

有没有一种不重复的好方法来实现这一点?

推荐答案

你可以用Borrowtrait 来做这个.如果您查看文档页面中的实现者,前三个在这里是相关的:这意味着f64&'a f64&'a mut f64都实现了Borrow<f64>.必须对迭代器生成的每个值调用borrow方法才能获得&f64.

use std::borrow::Borrow;

impl<T> Foo<T::Item> for T
    where T: Iterator,
          T::Item: Borrow<f64>
{
    fn bar(&mut self) -> f64 {
        unimplemented!()
    }
}

顺便说一句,在trait上定义一个类型参数,同时在该类型参数和supertrait的关联类型之间设置一个约束,这是没有意义的.类型T只能有一个Iterator的实现,因此它也只能有一个Foo的实现,尽管类型参数表明它可以实现许多不同的Foo<T>特征.因此,Foo上的类型参数是完全冗余的(您可以只使用supertrait的关联类型,而不是类型参数).因此,代码应该更像这样:

use std::borrow::Borrow;

trait Foo: Iterator {
    fn bar(&mut self) -> f64;
}

impl<T> Foo for T
    where T: Iterator,
          T::Item: Borrow<f64>
{
    fn bar(&mut self) -> f64 {
        unimplemented!()
    }
}

Rust相关问答推荐

将此字符串转换为由空格字符分隔的空格

展开枚举变量并返回所属值或引用

rust 迹-内存管理-POP所有权-链表

通过不同的字段进行散列和排序的 struct (需要不同的EQ实现)

可以为rust构建脚本编写单元测试吗?

如何在函数中返回自定义字符串引用?

无符号整数的Rust带符号差

在运行特定测试时,如何 suppress cargo test 的空输出?

Rust ndarray:如何从索引中 Select 数组的行

如何实现Deref;多次;?

为相同特征的特征对象使用 move 方法实现特征

.在 Rust 模块标识符中

当锁被释放时,将锁包装到作用域中是否会发生变化?

为什么 Rust 字符串没有短字符串优化 (SSO)?

pyO3 和 Panics

如果不满足条件,如何在 Rust 中引发错误

为什么-x试图解析为文字并在声明性宏中失败?

在 Rust 中有条件地导入?

如何在 Rust 的泛型函​​数中同时使用非拥有迭代器和消费迭代器?

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求