鍍金池/ 教程/ Scala/ 隱含參數(shù)(二)
轉(zhuǎn)換被方法調(diào)用的對象
View 限定
概述
當有多個隱含轉(zhuǎn)換可以選擇時
隱含參數(shù)(二)
隱含參數(shù)(一)
使用 implicits 的一些規(guī)則
隱含類型轉(zhuǎn)換

隱含參數(shù)(二)

隱含參數(shù)的另外一個用法是給前面明確定義的參數(shù)補充說明一些信息。 我們先給出一個沒有使用隱含參數(shù)的例子:

def maxListUpBound[T <:Ordered[T]](element:List[T]):T =
    element match {
      case List() =>
        throw new IllegalArgumentException("empty list!")
      case List(x) => x
      case x::rest =>
        val maxRest=maxListUpBound(rest)
        if(x > maxRest) x
        else maxRest
    }

這個函數(shù)是求取一個順序列表的最大值。但這個函數(shù)有個局限,它要求類型 T 是 Ordered[T]的一個子類,因此這個函數(shù)無法求一個整數(shù)列表的最大值。

下面我們使用隱含參數(shù)來解決這個問題。 我們可以再定義一個隱含參數(shù),其類型為一函數(shù)類型,可以把一個類型T轉(zhuǎn)換成 Ordered[T]。

def maxListImpParam[T](element:List[T])
                    (implicit orderer:T => Ordered[T]):T =
    element match {
      case List() =>
        throw new IllegalArgumentException("empty list!")
      case List(x) => x
      case x::rest =>
        val maxRest=maxListImpParam(rest)(orderer)
        if(orderer(x) > maxRest) x
        else maxRest
    }

在這個函數(shù)中,隱含參數(shù)使用中兩個地方,一個遞歸調(diào)用時傳入,第二個是檢查列表的表頭是否大于列表其余部分的最大值。這個例子的隱含參數(shù)給前面定義的類型T補充了一些信息,也就是如果比較兩個類型 T 對象。

這種用法非常普遍以至于 Scala 的庫缺省定義很多類型隱含的到 Ordered 類型的變換。例如我們調(diào)用這個函數(shù):

scala> maxListImpParam(List(1,5,10,34,23))
res2: Int = 34
scala> maxListImpParam(List(3.4,5.6,23,1.2))
res3: Double = 23.0
scala> maxListImpParam(List("one","two","three"))
res4: String = two

在這幾個調(diào)用中,編譯器自動為函數(shù)添加了對應的 orderer 參數(shù)。