flo*_*ero 6 traits type-constraints rust associated-types
我正在尝试定义具有关联类型的特征。我还希望关联类型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
}
Run Code Online (Sandbox Code Playgroud)
这个丑陋的where条款让我觉得应该有更好的方法。
这无法编译,因为这Item: AsRef<str>是非法构造:
trait Note {
type FieldsIter: Iterator<Item: AsRef<str>>;
//other fields and methods omitted
}
Run Code Online (Sandbox Code Playgroud)
这会失败,因为impl这里不允许:
trait Note {
type FieldsIter: Iterator<Item = impl AsRef<str>>;
//other fields and methods omitted
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,因为我想Iterator::Item实现某个特征,而不是成为具体类型。
trait Note {
type FieldsIter: Iterator<Item = AsRef<str>>;
//other fields and methods omitted
}
Run Code Online (Sandbox Code Playgroud)
您可以进行一点小小的改进,但除此之外,当前的语法正如您所发现的那样:
trait Note
where
<Self::FieldsIter as Iterator>::Item: AsRef<str>,
{
type FieldsIter: Iterator;
}
Run Code Online (Sandbox Code Playgroud)
这是消除歧义的语法,唯一的问题是还没有办法制作歧义版本!Rust 问题 #38078已开放以允许使用该Foo::Bar::Baz语法。
RFC 2289也作为改进这一点的一种方式开放。实施 RFC 后,您的第二个示例应该可以工作:
trait Note {
type FieldsIter: Iterator<Item: AsRef<str>>;
}
Run Code Online (Sandbox Code Playgroud)
现在可以解决此问题的一种方法类似于IntoIterator。这引入了另一个关联类型:
trait Note {
type FieldsIter: Iterator<Item = Self::Item>;
type Item: AsRef<str>;
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个,因为它引入了乍一看彼此正交的类型,但最终却紧密相关。