[英]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.