如何对关联类型的关联类型施加类型约束(例如Iterator::Item)?
How to impose a type constraint on the associated type of an associated type (e.g. Iterator::Item)?
我正在尝试定义具有关联类型的特征。我还希望关联类型实现 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
}
您可以做一点小改进,但除此之外,当前的语法如您所见:
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>;
}
我不喜欢这个,因为它引入的类型起初看起来彼此正交,但最终却紧密相关。
我正在尝试定义具有关联类型的特征。我还希望关联类型实现 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
}
您可以做一点小改进,但除此之外,当前的语法如您所见:
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>;
}
我不喜欢这个,因为它引入的类型起初看起来彼此正交,但最终却紧密相关。