2012-10-07 7 views
17

私はいくつかの方法が暗黙のパラメータ服用してクラスを定義しようとしている:私は別のクラスから、このクラスを使用するどのようにクラスレベルで暗黙のパラメータのデフォルト値を提供するために

object Greetings { 
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

implicit val greetings = "hello"    //> greetings : java.lang.String = hello 
Greetings.say("loic")       //> res0: String = hello loic 
Greetings.say("loic")("hi")      //> res1: String = hi loic 

私の問題は、Greetingsオブジェクトの外に暗黙のvalを定義した場合にのみ機能することです。 API(ScalaコレクションAPIなど)の使用を容易にするために、暗黙のパラメータを持つメソッドをクラス内にデフォルト値で提供できるようにしたいと考えています。

だから私はこれをやりたいが、(暗黙の値が見つからない)働いていない:

object Greetings { 
    implicit val greetings = "hello"  
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

、その後

Greetings.say("loic")       
Greetings.say("loic")("hi") 

を私は(implicit greetings: String = "hello")でデフォルト値を定義することができます知っているが、私はクラスレベルでそれをやりたいのですが、多くの方法がある場合は繰り返しません。

CanBuildFromListクラス内で定義されていることがわかりましたので、何かが足りないと思います。

答えて

6

私は回避策を見つけた:このように

class Greetings(implicit val greetings: String = "hello") { 
    def say(name: String): String = greetings + " " + name 
} 

私が欲しい場合、私は、デフォルト値を持っており、それを上書きすることができます。

new Greetings().say("loic")      //> res0: String = hello loic 

implicit val greetings = "hi"     //> greetings : java.lang.String = hi 
new Greetings().say("loic")      //> res1: String = hi loic 

new Greetings()("coucou").say("loic")   //> res2: String = coucou loic 

注:new Greetings()("coucou")new Greetings("coucou")、いない働いている、なぜなら構文違反の説明はhereです。

+0

暗黙的にのみ、通常のパラメータに2番目に挿入されますので、それは、不思議ではありません。通常、あなたのクラスは 'class Greetings()(暗黙のval ...)'のようになります。 – thatsIch

24

Stringのような一般的なタイプを暗黙的に使用することは悪い考えです。 主な理由は、暗黙的な参照が型のみに基づいているため、他の人がString型の別の暗黙的な値を定義するとどうなりますか?あなたは紛争に終わるかもしれません。したがって、独自の目的に合わせて独自のタイプを定義しなければなりません(Stringの単純なラッパー)。

暗黙の値を探すとき、コンパイラは暗黙の値型のコンパニオンオブジェクト(存在する場合)を(他の場所の中でも)探すことになります。コンパニオンオブジェクトは、(あなたの場合のように)デフォルトの暗黙的な値を設定する自然な場所であるため、その有用性を簡単に確認できます。しかし暗黙的な値があなたが所有していない型(例えばString)であれば、コンパニオンオブジェクトを書くことはできませんが、独自のラッパー型では問題はありません。ここ

OK、十分な言い回しは、あなたがそれを行うことができる方法である。

case class Greetings(value: String) { 
    override def toString = value 
} 
object Greetings { 
    // this implicit is just so that we don't have to manually wrap 
    // the string when explicitly passing a Greetings instance 
    implicit def stringToGreetings(value: String) = Greetings(value) 

    // default implicit Greetings value 
    implicit val greetings: Greetings ="hello" 

    def say(name: String)(implicit greetings: Greetings): String = greetings + " " +name 
} 
Greetings.say("loic")       
Greetings.say("loic")("hi") 
+0

私はそれを得る、多くの感謝:) – Loic

関連する問題