我正在尝试使用关联类型定义特征。我还希望关联类型实现Iterator
类型,而Item
类型实现AsRef<str>
。
虽然我知道如何针对某个函数或具体的Iterator::Item
类型执行此操作,但我无法针对原始情况提出一种清晰简洁的解决方案。
由于有用的错误消息,我的编译解决方案是:
trait Note
where
<<Self as Note>::FieldsIter as Iterator>::Item: AsRef<str>,
{
type FieldsIter: Iterator;
//other fields and methods omitted
}
丑陋的where
子句使我认为应该有更好的方法。
由于Item: AsRef<str>
是非法构造,因此无法编译:
trait Note {
type FieldsIter: Iterator<Item: AsRef<str>>;
//other fields and methods omitted
}
此操作失败,因为此处不允许使用impl
:
trait Note {
type FieldsIter: Iterator<Item = impl AsRef<str>>;
//other fields and methods omitted
}
由于我希望Iterator::Item
实现某种特征而不是具体类型,因此无法编译。
trait Note {
type FieldsIter: Iterator<Item = AsRef<str>>;
//other fields and methods omitted
}
答案 0 :(得分:2)
您可以进行一些小的改进,但是除此之外,当前的语法是您发现的:
trait Note
where
<Self::FieldsIter as Iterator>::Item: AsRef<str>,
{
type FieldsIter: Iterator;
}
这是歧义化的语法,唯一的问题是还没有一种方法可以制作出模棱两可的版本! Rust issue #38078已打开,允许使用Foo::Bar::Baz
语法。
RFC 2289也可以作为一种改进方法。实施RFC后,您的第二个示例应该可以工作:
trait Note {
type FieldsIter: Iterator<Item: AsRef<str>>;
}
现在可以解决此问题的一种方法类似于IntoIterator
。这引入了另一种关联类型:
trait Note {
type FieldsIter: Iterator<Item = Self::Item>;
type Item: AsRef<str>;
}
我不喜欢这样做,因为它引入的类型乍一看彼此正交,但最后紧密相关。