这是你所要求的:
trait TextBoard: Board
where
Self::Move: Debug,
{
}
所有对特征的限制都必须在"headline"中,不能在编写特征的正文中添加额外的限制。这个限制将防止你在<Foo as Board>::Move
没有实现Debug
时编写impl TextBoard for Foo
(playground)。
也许这正是您想要的,但您真的需要防止为其他类型实现TextBoard
吗?对于某些类型,可能有另一种编写print_moves
更合理的方法,而Debug
要求只是噪音。在这种情况下,您可能希望跳过where
子句并将print_moves
的正文移动到全局impl
中:
trait TextBoard {
fn print_moves(&self);
}
impl<B: Board> TextBoard for B
where
B::Move: Debug,
{
fn print_moves(&self) {
println!("{:?}", self.moves());
}
}
这个版本中,你依然不需要为那些 Self::Move: Debug
的类型编写一个 impl
,但是你也不会被阻止为其他一些不满足条件的类型编写 impl
。这更像是一种扩展而不是改进。
另一方面,几乎总是应该为每种类型实现 Debug
,那么这个 trait 真的有用吗?也许你只想在 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
。
printMoves
,它接受一个&Board<Move = T>
,其中T: fmt::Debug
,这样做能解决你的问题吗?或者你坚持使用改进的trait? - Matthieu M.