Aliasing Traits

2015/07/26 10:10am

(2020-04-04) Trait alias は RFC 1733 で導入された。

RustTraits による制約は Associated Types や複数の Traits を + で指定したりすると、どんどん長くなってしまう。

struct A<T: Iterator<Item=char>> {
    ...
}

通常の型には type キーワードによる別名づけの手段が用意されているが、これは Traits には使えない。

type CharIterator = Iterator<Item=char>;

// ERROR: note: `type` aliases cannot be used for traits
struct A<T: CharIterator> {
    ...
}

過去に提案はあったが却下されたようだ。

Allow type to create an alias for several trait bounds · Issue #8634 · rust-lang/rust

  1. 別名を与えたい Trait を継承した空の Trait をつくればいい
  2. 言語に新しい機能をつけくわえるほどの価値はなさそう

たしかに、空の Trait をつくることで似たような効果を得ることはできる。

trait CharIterator: Iterator<Item=char> {}

struct A<T: CharIterator> {
    ...
}

ただし、既存の Iterator<Item=char> を実装している型 (std::str::Chars など) は、今回追加した CharIterator を実装しているわけではないので、このままだと T の実体として使うことができない。

Iterator<Item=char> を実装した型が CharIterator も実装している」という impl を書いておこう。

trait CharIterator: Iterator<Item=char> {}
impl<T: Iterator<Item=char>> CharIterator for T {}

struct A<T: CharIterator> {
    it: T,
}

...

let a = A { it: "test".chars() };

参考にした記事