Scala Implicit Parameters函數
若是定義函數時,標明某一參數爲implicit,則這個參數是隱式參數。看起來與缺省參數(Default Parameters)相似,調用者沒必要在調用時指定該參數。spa
可是就實際運行機制而言,隱式參數與缺省參數是徹底不同的。缺省參數是函數定義方設定了一個缺省值,在調用者沒有指明時將使用該缺省值。 隱式參數則不一樣,最終是會由調用方指定參數值,只是不必定在調用的語句裏指定而已。編譯器在發現缺乏隱式參數時,會在程序範圍內尋找符合類型的隱式值,若是找不到則編譯會失敗。scala
以下代碼,code
abstract class Logger { def log(s: String) } class FileLogger extends Logger { def log(s: String) { println("Log in file: " + s) } } class StdoutLogger extends Logger { def log(s: String) { println("Stdout: " + s) } } def Add(a: Int, b: Int)(implicit logger: Logger) { val sum = a + b logger.log("%d + %d = %d".format(a, b, sum)) } implicit val log = new FileLogger Add(1, 2) Add(2, 3)(new StdoutLogger) //you may do it explicitly
運行並輸出,orm
C:\WorkSpace6-scala\scala-train\src\com\usoft>scala implicit_parameter.scalablog
Log in file: 1 + 2 = 3繼承
Stdout: 2 + 3 = 5ci
若是上述代碼沒有implicit val log = new FileLogger這一句,在代碼範圍內也沒有其餘的Logger類型的implicit值,編譯器會報錯:編譯器
could not find implicit value for parameter logger: com.scalass.examples.blog.ImplicitParameters.Loggerit
反之,若是能找到Logger類型的隱式值,編譯器會將該隱式值做爲參數傳遞過去。
與隱式轉換同樣,你也能夠選擇顯示的傳遞隱式參數,實際上編譯器就是這樣作的,在程序上下文找到符合類型要求的隱式值,將它顯示的做爲參數傳遞。 也與隱式轉換同樣,隱式值的名稱對編譯器並沒有影響,只要類型符合便可,可是爲了可讀性,建議賦予它合適的名稱。
到這裏可能你會有些想法了,其實一樣的功能可能能夠由依賴注入等方式實現。在使用依賴注入,或是繼承等方式能實現的狀況下,咱們不建議使用隱式轉換或隱式參數。 由於其餘的方式,代碼結構可能會更清晰,而過多的使用隱式轉換或隱式參數經常會讓讀者摸不着頭腦。
============END============