[譯] Scala 類型的類型(六)

上一篇

Scala 類型的類型(五)ide

目錄

26. 聯合類型

❌ 本部分還沒有完成,但你能夠經過 Miles 的博客(下方有連接)得到更多瞭解 :-)函數

讓咱們開始來討論這個類型,此次要藉助下「集合論」,而後把咱們已經學過的 A with B 當作一個「交集類型」。spa

爲何呢?由於只有同時帶有類型 A 和類型 B 的對象才能符合這個類型,所以在集合論中,它將是一個交集。此外,咱們思考下什麼是「聯合類型」。scala

這是兩個集合的聯合,逐集看每一個元素的類型要麼是 A 或者 B。咱們的任務是使用 Scala 類型系統來引入這樣的類型。雖然它們不是 Scala 中的第一等構造(不是內置的),咱們也能夠很容易地實現和使用它們。Miles Sabin 在博客中經過「 Curry-Howard 同構」深刻地解釋了這一技術,若是你比較好奇,能夠去看看。code

type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (TU) }

def size[T : (Int |∨| String)#λ](t : T) = t match {
    case i : Int => i
    case s : String => s.length
}複製代碼

27. 延遲初始化

自從咱們開始討論 Scala 中一些不常見的類型,咱們就會安排專門的章節來介紹每個類型。延遲初始化(Delayed Init)實際上只是一種編譯器的技巧而已,它對類型系統而言並非很是重要。可是一旦你理解了它,就會明白 scala.App 是如何運做的,因此看看下面的例子吧:對象

object Main extends App {
  println("Hello world!")
}複製代碼

查看這段代碼,根據咱們已知的 Scala 基礎知識,會下這樣結論:「那麼,println 是在 Main 類的構造函數中!」。這一般是對的,但在這裏卻並非這樣的,由於 App 繼承了 DelayedInit 特質:繼承

trait App extends DelayedInit {
  // code here ...
}複製代碼

讓咱們來看看延遲初始化的特質的完整源代碼:get

trait DelayedInit {
  def delayedInit(x: => Unit): Unit
}複製代碼

正如你所見,它並無包含任何的實現 — 全部圍繞它的工做實際上都是編譯器執行的,它將以一種特殊的方式來對待「繼承了 DelayedInit」的類和單例(注:特質不會像這樣同樣重寫)。編譯器

特殊待遇是這樣子的:博客

  • 假設你的類/單例主體是一個函數,處理主體中要作的全部事情
  • 編譯器爲你建立了這個函數,並將它傳遞給了延遲初始化方法(x: => Unit),

咱們立刻來舉個例子,手動來從新實現一遍 App 爲咱們自動作的事情(在 delayedInit 的幫助下):

// we write:
object Main extends DelayedInit {
  println("hello!")
}

// the compiler emits:
object Main extends DelayedInit {
  def delayedInit(x: => Unit = { println("Hello!") }) = // impl is left for us to fill in
}複製代碼

使用這種機制,你能夠隨時運行你的類的主體。咱們已經瞭解了延遲初始化如何工做,接下來再來實現下咱們本身版本的 scala.App 吧(這實際上也是以相同方式實現的)。

override def delayedInit(body: => Unit) {
    initCode += (() => body)
  }

  def main(args: Array[String]) = {
    println("Whoa, I'm a SimpleApp!")

    for (proc <- initCode) proc()

    println("So long and thanks for all the fish!")
  }
}

                                // Running the bellow class would print print:
object Test extends SimpleApp { //
                                // Whoa, I'm a SimpleApp!
  println(" Hello World!")     // Hello World!
                                // So long and thanks for all the fish!
}複製代碼
相關文章
相關標籤/搜索