簡體   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