繁体   English   中英

具有比supertrait更严格的相关类型边界的特征

[英]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没有实现Debugplayground )时,此绑定将阻止您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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM