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

鍍金池/ 教程/ Scala/ View 限定
轉(zhuǎn)換被方法調(diào)用的對(duì)象
View 限定
概述
當(dāng)有多個(gè)隱含轉(zhuǎn)換可以選擇時(shí)
隱含參數(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ù)體部分有機(jī)會(huì)使用 implicit 卻沒(méi)有使用。要注意的是當(dāng)年在參數(shù)中使用 implicit 類型時(shí),編譯器不僅僅在需要時(shí)補(bǔ)充隱含參數(shù),而且編譯器也會(huì)把這個(gè)隱含參數(shù)作為一個(gè)當(dāng)前作用域內(nèi)可以使用的隱含變量使用,因此在使用隱含參數(shù)的函數(shù)體內(nèi)可以省略掉 implicit 的調(diào)用而由編譯器自動(dòng)補(bǔ)上。

因此代碼可以簡(jiǎn)化為:

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)類型不匹配,編譯器不會(huì)馬上停止編譯,相反,它會(huì)檢查是否有合適的隱含轉(zhuǎn)換來(lái)修補(bǔ)代碼,在本例中,它發(fā)現(xiàn) orderer 可用。因此編譯器自動(dòng)改寫為 orderer(x)> maxRest。同理我們?cè)谶f歸調(diào)用 maxList 省掉了第二個(gè)隱含參數(shù),編譯器也會(huì)自動(dòng)補(bǔ)上。 同時(shí)我們發(fā)現(xiàn),maxList 代碼定義了隱含參數(shù) orderer,而在函數(shù)體中沒(méi)有地方直接引用到該參數(shù),因此你可以任意改名 orderer,比如下面幾個(gè)函數(shù)定義是等價(jià)的:

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 中專門定義了一種簡(jiǎn)化的寫法– 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 限定,也就是說(shuō),我可以使用任意類型的 T,只要它可以看成類型 Ordered[T]。這和 T 是 Orderer[T]的子類不同,它不需要 T 和 Orderer[T]之間存在繼承關(guān)系。 而如果類型 T 正好也是一個(gè) Ordered[T]類型,你也可以直接把 List[T]傳給 maxList,此時(shí)編譯器使用一個(gè)恒等隱含變換:

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

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