[英]Why are supertrait bounds other than the first not recognized on an associated type?
[英]Traits with stricter associated type bounds than supertrait
我有一个简单的特征,其关联类型没有边界。
trait Board {
type Move;
fn moves(&self) -> Vec<Self::Move>;
}
我也想把这个特性用作超级特征。 特别是,我希望我的新子特征对相关类型有更严格的界限。 像这样的东西:
trait TextBoard: Board {
type Move: fmt::Debug; // Trying to tighten bounds on associated type
fn printMoves(&self) {
println!("{:?}", self.moves());
}
}
这个例子是高度简化的,但似乎显示了问题:编译器认为我正在尝试创建一个新的关联类型,但我只是想让子文章需要更严格的边界。 有没有办法实现这个目标?
这是你要求的:
trait TextBoard: Board
where
Self::Move: Debug,
{
// ...
}
特质的所有界限都必须在“标题”中; 一旦开始编写特征的主体,就不能施加额外的限制。 当<Foo as Board>::Move
没有实现Debug
( playground )时,此绑定将阻止您impl TextBoard for Foo
编写impl TextBoard for Foo
。
也许这就是你想要的,但你真的需要阻止为其他类型实现TextBoard
吗? 对于某些类型,可能有另一种方法来编写更有意义的print_moves
,而Debug
要求只是噪声。 在这种情况下,您可能希望跳过where
子句并将print_moves
的主体移动到毯子impl
:
trait TextBoard {
fn print_moves(&self);
}
impl<B: Board> TextBoard for B
where
B::Move: Debug, // or <Self as Board>::Move: Debug
{
fn print_moves(&self) {
println!("{:?}", self.moves());
}
}
对于这个版本,你仍然不需要为Self::Move: Debug
类型编写一个impl
,但是你不能阻止为其他不支持的类型写一个impl
。 它更像是一个扩展,而不是一个改进 。
另一方面,你应该总是为每种类型实现Debug
,所以拥有这个特性真的很有用吗? 也许你想要的是只是一个可选的方法Board
多数民众赞成实现时Move: Debug
:
trait Board {
type Move;
fn moves(&self) -> Vec<Self::Move>;
fn print_moves(&self)
where
Self::Move: Debug,
{
println!("{:?}", self.moves());
}
}
这与原始版本类似,但不需要添加新的TextBoard
特性,因此它可能会减少您必须编写的显式边界的数量。 许多标准库特性(如Iterator
都具有使用这样的边界定义的可选方法。 除了Move
必须 Debug
的要求之外,其缺点是它使用打印代码使Board
特征变得混乱,您可能不会认为它实际上是Board
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.