在 Trait 中要求所有 Iterators<Item = Self> 都实现 Trait

问题描述 投票:0回答:1

非常具体地,我有一个特征

LogSumExp
,它适用于所有
Iterator<Item = f32>
Iterator<Item = f64>

我有自己的特征

FloatTrait
,它仅针对
f32
f64
实现,帮助我将程序中的特征界限保持在最低限度,但仍然对这两种类型具有通用性。

我想表达任何

Iterator<Item : FloatTrait> : LogSumExp

这有可能吗?

rust types traits
1个回答
2
投票

不,不可能表达“对于一个类型X

来实现
FloatTrait
,它也必须意味着所有
Iterator<Item=X>: LogSumExp
。您可以通过在特征定义中使用
Self
 子句来提供不直接在 
where
 上的附加约束,但要做您想要的事情将需要某种尚不存在的更高级的约束支持。


旧答案解决了不同的角度:

即使

FloatTrait

 没有实现超出 
f32
f64
 范围,编译器仍会假设可能存在其他实现。因此 
FloatTrait
 约束不仅仅是 
f32
 | 的别名。 
f64
,因此 
Iterator<Item: FloatTrait>: LogSumExp
 不能仅仅因为 
Iterator<Item = f32>: LogSumExp
Iterator<Item = f64>: LogSumExp
 就被假定为真。

为了获得这种行为,您必须精心设计您的实现,使其

确实涵盖所有FloatTrait

可能性(已知和未知)。你必须这样做,而不是单独的
impl

impl<I> LogSumExp for I where I: Iterator, I::Item: FloatTrait { ... }
如果这听起来很愚蠢,因为不可能存在其他实现(由于是私有的,或密封的,或在二进制板条箱中),那么您并不孤单。实现和约束的孤儿规则和特征一致性是围绕板条箱之间的稳定可扩展性而设计的,这意味着它们是仅限本地板条箱的东西的眼中钉。

© www.soinside.com 2019 - 2024. All rights reserved.