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

鍍金池/ 教程/ Scala/ Scala 課堂:高級(jí)類型(一)
Scala 課堂:高級(jí)類型(二)
Scala 課堂:基礎(chǔ)(三)
Scala 課堂:類型和多態(tài)類型(一)
Scala 課堂:基礎(chǔ)(二)
Scala課堂:基礎(chǔ)(五)
Scala 課堂:基礎(chǔ)(四)
Scala 課堂:基礎(chǔ)(六)
Scala 課堂:集合(二)
Scala課堂:類型和多態(tài)類型(二)
Scala 課堂:模式匹配和函數(shù)組合
Scala 課堂:高級(jí)類型(一)
Scala 課堂:集合(一)
Scala 課堂:基礎(chǔ)(一)

Scala 課堂:高級(jí)類型(一)

這里我們轉(zhuǎn)載 (Twitter 的 Scala 課堂](http://twitter.github.io/scala_school/zh_cn/collections.html),轉(zhuǎn)載的內(nèi)容基本來(lái)自 Twitter 的 Scala 課堂中文翻譯,部分有小改動(dòng).

視界(“View”)

有時(shí)候,你并不需要指定一個(gè)類型是等/子/超于另一個(gè)類,你可以通過(guò)轉(zhuǎn)換這個(gè)類來(lái)偽裝這種關(guān)聯(lián)關(guān)系。一個(gè)視界指定一個(gè)類型可以被“看作是”另一個(gè)類型。這對(duì)對(duì)象的只讀操作是很有用的。 隱 函數(shù)允許類型自動(dòng)轉(zhuǎn)換。更確切地說(shuō),在隱式函數(shù)可以幫助滿足類型推斷時(shí),它們?cè)试S按需的函數(shù)應(yīng)用。例如:


scala> implicit def strToInt(x: String) = x.toInt
strToInt: (x: String)Int

scala>  "123"
res0: String = 123

scala> val y:Int="123"
y: Int = 123

scala>  math.max("123", 111)
res1: Int = 123

視界,就像類型邊界,要求對(duì)給定的類型存在這樣一個(gè)函數(shù)。您可以使用<%指定類型限制,例如


scala> class Container[A <% Int] { def addIt(x: A) = 123 + x }
defined class Container

這是說(shuō) A 必須“可被視”為 Int 。讓我們?cè)囋?/p>


scala> class Container[A <% Int] { def addIt(x: A) = 123 + x }
defined class Container

scala>  (new Container[String]).addIt("123")
res2: Int = 246

scala>  (new Container[Int]).addIt(123) 
res3: Int = 246

scala> (new Container[Float]).addIt(123.2F)
<console>:10: error: No implicit view available from Float => Int.
              (new Container[Float]).addIt(123.2F)

 其他類型限制

方法可以通過(guò)隱含參數(shù)執(zhí)行更復(fù)雜的類型限制。例如,List 支持對(duì)數(shù)字內(nèi)容執(zhí)行 sum,但對(duì)其他內(nèi)容卻不行??墒恰cala 的數(shù)字類型并不都共享一個(gè)超類,所以我們不能使用 T


sum[B >: A](implicit num: Numeric[B]): B

如果你調(diào)用 List(1,2).sum(),你并不需要傳入一個(gè) num 參數(shù);它是隱式設(shè)置的。但如果你調(diào)用 List(“whoop”).sum(),它會(huì)抱怨無(wú)法設(shè)置 num。 在沒有設(shè)定陌生的對(duì)象為 Numeric 的時(shí)候,方法可能會(huì)要求某種特定類型的“證據(jù)”。這時(shí)可以使用以下類型-關(guān)系運(yùn)算符:

|:----------|:-----------------|
|A =:= B |A 必須和 B相等 |
|A <:< B |A 必須是 B 的子類 |
|A <%< B |A 必須可以被看做是 B|


scala>  class Container[A](value: A) { def addIt(implicit evidence: A =:= Int) = 123 + value }
defined class Container

scala>  (new Container(123)).addIt
res5: Int = 246

scala>  (new Container("123")).addIt
<console>:10: error: Cannot prove that String =:= Int.
               (new Container("123")).addIt

                                      ^

使用視圖進(jìn)行泛型編程

在 Scala 標(biāo)準(zhǔn)庫(kù)中,視圖主要用于實(shí)現(xiàn)集合的通用函數(shù)。例如“min”函數(shù)(在 Seq[] 上)就使用了這種技術(shù):


def min[B >: A](implicit cmp: Ordering[B]): A = {
  if (isEmpty)
    throw new UnsupportedOperationException("empty.min")

  reduceLeft((x, y) => if (cmp.lteq(x, y)) x else y)
}

其主要優(yōu)點(diǎn)是:

集合中的元素并不是必須實(shí)現(xiàn) Ordered 特質(zhì),但 Ordered 的使用仍然可以執(zhí)行靜態(tài)類型檢查。 無(wú)需任何額外的庫(kù)支持,你也可以定義自己的排序:


scala>  List(1,2,3,4).min
res0: Int = 1

scala>  List(1,2,3,4).min(new Ordering[Int] { def compare(a: Int, b: Int) = b compare a })
res1: Int = 4

作為旁注,標(biāo)準(zhǔn)庫(kù)中有視圖來(lái)將 Ordered 轉(zhuǎn)換為 Ordering (反之亦然)。


trait LowPriorityOrderingImplicits {
  implicit def ordered[A <: Ordered[A]]: Ordering[A] = new Ordering[A] {
    def compare(x: A, y: A) = x.compare(y)
  }
}

上下文邊界和 implicitly[]

Scala2.8引入了一種串聯(lián)和訪問(wèn)隱式參數(shù)的快捷方式。


scala> def foo[A](implicit x: Ordered[A]) {}
foo: [A](implicit x: Ordered[A])Unit

scala>  def foo[A : Ordered] {}        
foo: [A](implicit evidence$1: Ordered[A])Unit

隱式值可能會(huì)通過(guò) implicitly 被訪問(wèn)


scala>  implicitly[Ordering[Int]]
res5: Ordering[Int] = scala.math.Ordering$Int$@4b7773c4