2012-10-07 74 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")定義默認值,但我想在課堂上做到這一點,以避免重複,如果有很多方法。例如

我想我錯過了一些東西,因爲我看到List類中定義了CanBuildFrom

回答

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

這是不奇怪的,因爲隱含只會第二插入到正常參數。通常情況下你的類會是什麼樣子'類的問候()(隱式VAL ...)' – thatsIch

24

這是一個壞主意,在隱式使用這種類型一般作爲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