在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

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

View 限定

上篇的例子

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ù)體部分有機會使用 implicit 卻沒有使用。要注意的是當年在參數(shù)中使用 implicit 類型時,編譯器不僅僅在需要時補充隱含參數(shù),而且編譯器也會把這個隱含參數(shù)作為一個當前作用域內(nèi)可以使用的隱含變量使用,因此在使用隱含參數(shù)的函數(shù)體內(nèi)可以省略掉 implicit 的調(diào)用而由編譯器自動補上。

因此代碼可以簡化為:

def maxList[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=maxList(rest)
        if(x > maxRest) x
        else maxRest
    }

編譯在看到 x > maxRest 發(fā)現(xiàn)類型不匹配,編譯器不會馬上停止編譯,相反,它會檢查是否有合適的隱含轉(zhuǎn)換來修補代碼,在本例中,它發(fā)現(xiàn) orderer 可用。因此編譯器自動改寫為 orderer(x)> maxRest。同理我們在遞歸調(diào)用 maxList 省掉了第二個隱含參數(shù),編譯器也會自動補上。 同時我們發(fā)現(xiàn),maxList 代碼定義了隱含參數(shù) orderer,而在函數(shù)體中沒有地方直接引用到該參數(shù),因此你可以任意改名 orderer,比如下面幾個函數(shù)定義是等價的:

def maxList[T](element:List[T])
                    (implicit orderer:T => Ordered[T]):T =
    ...
def maxList[T](element:List[T])
                    (implicit iceCream:T => Ordered[T]):T =
    ...

由于在 Scala 這種用法非常普遍,Scala 中專門定義了一種簡化的寫法– View 限定。如下:

def maxList[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=maxList(rest)
        if(x > maxRest) x
        else maxRest
    }

其中 <% 為 View 限定,也就是說,我可以使用任意類型的 T,只要它可以看成類型 Ordered[T]。這和 T 是 Orderer[T]的子類不同,它不需要 T 和 Orderer[T]之間存在繼承關(guān)系。 而如果類型 T 正好也是一個 Ordered[T]類型,你也可以直接把 List[T]傳給 maxList,此時編譯器使用一個恒等隱含變換:

implicit def identity[A](x:A): A =x 

在這種情況下,該變換不做任何處理,直接返回傳入的對象。