2016-03-04 9 views
7

私は形質がTraitであり、関連する型がTrait::Associatedである。ここに示したように、私は、それはそれに関連する種類によってインデックス可能することを要求することによって、形質を拘束しようとしています:形質と関連する型をパラメータとして使用して形質を束縛する

use std::ops::Index; 

pub trait Trait: Index<Trait::Associated> { 
    type Associated; 
} 

をしかし、コンパイラは、関連するタイプが

error: ambiguous associated type; specify the type using the syntax <Type as Trait>::Associated [E0223]

pub trait Trait: Index<Trait::Associated> 
         ^~~~~~~~~~~~~~~~~ 

曖昧であることを不平を言う私も試してみました関連する型を Self::Associatedと呼んでいますが、コンパイラは型と型の間の循環参照について抗議します。

は最後に、私はまた、明示的にTraitためIndexを実装してみました:

pub trait Trait { 
    type Associated; 
} 

impl<T: Trait> Index<T::Associated> for T { 
    type Output = str; 
    fn index(&self, associated: T::Associated) -> &'static str { "sup" } 
} 

残念ながら、それはあまりにも失敗します。

error: type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter

私はここで無理に何かをしようとしていますか?ジェネリックを使わずに、同様のことを達成する方法はありますか?

Playpen link

答えて

9

あなたはとても近くにいます。

答えは簡単です:Traitは、単にその定義でTraitへの参照は、あなたもTraitを実装する他のタイプを参照するために望むことができるすべての後に、現在の型を参照することを想定していません。

特定のタイプを指定するには、ヒントを参考にしてください。<Type as Trait>::Associatedを使用してください。Typeが現在のタイプです。

したがって、Traitを定義する際に、インスタンス化される具体的なタイプをどのように参照しますか? Selfを使用しています。

ソリューションは、このようにして、次のとおりです。私は、次の2番目の試みのアプローチを取って、あなたが欲しいのセマンティクスを提供

pub trait Trait: Index<<Self as Trait>::Associated> { 
    type Associated; 
} 
+0

ありがとう、それは完璧に機能しました!ちなみに、私の3回目の試み(traitの定義と 'impl'ブロックが別々のもの)を作る方法はありますか?私が 'impl'行に' Self'を使用しようとすると、rustcは文句を言います。 – Jean

+1

@Jean:構文は 'impl Index < :: Associated> for T'ですが、ここで一貫性の問題があります。独自のクレートのタイプの別のクレートから 'trait'を実装することはできません(与えられたタイプに対して与えられた特性の実装が矛盾している複数の人を避けるため)。ここで、 'T'はあなたのクレートの種類に制限されていないので...禁止されています。 –

1

と思います。

pub trait Trait { 
    type Associated; 
} 

impl<T> Index<T> for Trait<Associated=T> { 
    type Output=str; 
    fn index(&self, associated: T) -> &'static str { "sup" } 
} 
関連する問題