2013-03-07 16 views
6

を持つ形質のメソッドを実装する:私は、オブジェクトがトレイト<code>Iterable</code>を実装し、実装方法に追加の暗黙のパラメータを渡したい追加の暗黙のパラメータ

object MyRepository extends Iterable[Something] { 

    def iterator(implict entityManager: EntityManager): Iterator[Something] = ... 

} 

iterator方法はありませんを持っているので、明らかにこれは動作しません。暗黙的なパラメータであるため、上記の方法では実装されていません。

例のユースケースは、私は、リポジトリの値に適用するmap方法です:

def get = Action { 
    Transaction { implicit EntityManager => 
     val result = MyRepository.map(s => s ...) 
    } 
    } 

Iterable形質を実装し、暗黙のpramameterをキャプチャするためにいくつかの方法はありますか?

+0

私は非常に努力しましたが、あなたが言っていることを理解できませんでした。あなたの質問に言いたいことがありますか? –

+0

@RégisJean-Gilles:私は例を追加して、それが私の意図を示すことを願っています。 – deamon

+0

ああ、もちろん、私は参照してください。 'Iterable.iterator'を実装したいが、元の署名に明示的に定義されていない追加の暗黙的なパラメータ(実装時)が必要です。 –

答えて

9

Iterable.iteratorにはこの署名が暗黙的に指定されていないため、暗黙的にこのメソッドを実装することはできません。これは別のメソッド(具体的には別のオーバーロード)です。

しかし、MyRepositoryがオブジェクトではなくクラスだった場合は、クラスコンストラクタで暗黙的に取得できます。 同じ使用スタイル(new MyRepository.map{ ... }ではなくのように)を使用したい場合は、オブジェクトからクラスへの暗黙的な変換を行うことができます。ここで

は一例です:

object MyRepository { 
    class MyRepositoryIterable(implicit entityManager: EntityManager) extends Iterable[Something] { 
    def iterator: Iterator[Something] = ??? 
    } 
    implicit def toIterable(rep: MyRepository.type)(implicit entityManager: EntityManager): MyRepositoryIterable = new MyRepositoryIterable 
} 

あなたがMyRepository.map(...)を行うときに、今何が起こるオブジェクトが暗黙的に暗黙のEntityManager値をキャプチャMyRepositoryIterableのインスタンスに変換されるということです。 MyRepositoryIterableは、実際にIterableを実装するクラスです。

+0

それは、トランザクションごとに新しいリポジトリを作成する必要があることを意味しませんか? – deamon

+1

いいえ、「MyRepository」はまだオブジェクトです(したがって一意です)。あなたのサンプルコード( 'get'メソッド)は変更なしでそのまま動作しますが、' map'の呼び出しは暗黙のうちに 'MyRepositoryIterable'インスタンスの作成を必要とします(しかしこれは透明です)。 –

関連する問題