Scala Implicit Parameters

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============

相關文章
相關標籤/搜索