2016-06-24 25 views
1

明示的なインポートをせずにコンパニオンオブジェクトから暗黙的に取得することは可能ですか?明示的なインポートがない暗黙ですか?

私は次のような場合があります。私が達成したい何

trait Foo[A] { 
    def foo(f: A): String 
} 

case class Bar(name: String) 

object Bar { 
    implicit object FooBar extends Foo[Bar] { 
    def foo(f: Bar) = f.name 
    } 
} 

class TestImplicits[T] { 
    def sayFoo(t: T)(implicit ev: Foo[T]) = ev.foo(t) 

    def sayFooIndirect(t: T) = sayFoo(t) 
} 

はTestImplicitsをインスタンス化し、トンネルにsayFoo方法にそれを通じて暗黙のを必要とせずにsayFooIndirectメソッドを呼び出すことができるのです。

val b = new Bar("test") 
val t = new TestImplicit[Bar] 
t.sayFooIndirect(b) 

コードはコンパイルされません。しかし:

could not find implicit value for parameter ev: Foo[T] 
    def sayFooIndirect(t: T) = sayFoo(t) 
            ^

答えて

2

を私は答えがあると思いますが、あなたは

class TestImplicits[T] { 
    def sayFoo(t: T)(implicit ev: Foo[T]) = ev.foo(t) 
    def sayFooIndirect(t: T) = sayFoo(t) 
} 

sayFooすることはできませんがでなければならないことを、パラメータevを取りますあなたがそれを明示的または暗黙的に呼び出すときに提供されます。

sayFooIndirectの本文には、タイプの暗黙オブジェクトはありません。それを利用できるようにするには、どこにでも暗黙的に渡すか、他の方法で範囲に入れます。あなたのクラスはタイプTで修正されているので、暗黙的にFoo[T]をコンストラクタに取り込むことができます。

val b = new Bar("test") 
val t = new TestImplicits[Bar] 
t.sayFooIndirect(b) 
+0

ありがとう:

class TestImplicits[T](implicit ev: Foo[T]) { def sayFoo(t: T) = ev.foo(t) def sayFooIndirect(t: T) = sayFoo(t) } 

動作します以下この方法を使用します。私は、あまりにも暗黙のうちに暗黙的に必要なメソッドに追加することに集中していました。しかし、それをコンストラクタに追加することは、私のユースケースでうまく動作します。 –

関連する問題