2016-04-09 17 views
3

オーバーライドできるクラスに暗黙的に実装したいと思います。以下のとおり:私はコンパニオンオブジェクトまたは形質に一般的な暗黙のTool実装を定義する場合オーバーライド可能な暗黙的な構造を構築する

tooling.scala

package tooling  

case class Tool(msg: String) 

class Toolkit{ 
    def usingTool(source:String)(implicit tool:Tool){ 
    println(s"[$source] using tool: ${tool.msg}") 
    } 
} 

user.scala

package user 

class User{ 
    val toolkit = new Toolkit() 

    def usingGenericTool(){ 
    toolkit.usingTool("from generic usage") 
    } 

    def usingSpecificTool(){ 
    implicit lazy val tool = Tool("shovel") 
    toolkit.usingTool("from generic usage") 
    } 
} 

を、私は警告を受けますそのツールと暗黙的な総称はambiguous implicit valuesです。

どのようにして、メソッドのスコープでオーバーライドして、さまざまなクラスで再利用できる汎用暗黙のvalを定義できますか?彼らは普通のものであるかのように

答えて

0

あなただけすなわち、implicitパラメータを追加することができます。

toolkit.usingTool("from generic usage")(Tool("shovel")) 

をもそれぞれ暗黙のメンバーが優先される - 暗黙の上位クラスで定義されていてもして、親クラスで定義された暗黙に優先します別の名前。

したがって、次の例では、2を印刷します:

trait LowPriorityImplicit { 
    implicit val x = 1 
} 

object Test extends LowPriorityImplicit { 
    implicit val y = 2 

    def f(implicit i: Int) = println(i) 

    f // => 2 
} 
+0

私はそのメソッドを何回か呼び出しているので、私は望んでいません – dstibbe

+0

私が知る限り、同じクラスに定義されたimplicitsの優先メカニズムはありません。クラス階層の暗黙のために - 私は私の答えを更新しました。 – Maxim

+0

しかし、あなたがあなたの例で示したように、私がTestの特性に暗黙的に定義しているのであれば、Testクラスのメソッド本体に暗黙的に定義することはできません。 – dstibbe

0

Toolのコンパニオンオブジェクト内の暗黙のデフォルトを定義します。

case class Tool(msg: String) 
object Tool { 
    implicit val defaultTool: Tool = Tool("Generic") 
} 

そして、あなたは他のツールをインポートする、または作成することによって、それを上書きすることができます暗黙的Tool変数:

object Tools { 
    implicit val Special: Tool = Tool("special") 
} 

def usingTools(): Unit = { 
    val toolkit = new Toolkit() 
    toolkit.usingTool("using the default") 

    { // importing an override 
    import Tools.Special 
    toolkit.usingTool("using imported") 
    } 

    { // creating an override 
    implicit val anotherTool: Tool = Tool("local") 
    toolkit.usingTool("using local implicit val") 

    // using a Tool other then the currently imported as an exception: 
    toolkit.usingTool("overriding once manually")(Tool("manual")) 
    } 
} 
関連する問題