2017-05-25 169 views
1

我想學習斯卡拉語言。
在許多文檔或視頻教程中,我看到scala開發人員創建空的類或對象,並將其用於另一個類作爲參數或實現空的特徵!
例如:斯卡拉空課堂,對象,特質

object Controller { 
    sealed trait Controller 
    case object Login extends Controller 
    case object Logout extends Controller 
} 

或者這樣:

sealed trait Expression 
case class Number(num: Int) extends Expression 
case class Plus(a: Expression, b: Expression) extends Expression 
case class Minus(a: Expression, b: Expression) extends Expression 

object ExpressionEvaluate { 
    def value(expression: Expression): Int = expression match { 
    case Number(value) => value 
    case Plus(a, b) => value(a) + value(b) 
    case Minus(a, b) => value(a) - value(b) 
    } 
} 

我想知道這是什麼模式呢?
什麼是空義類,對象或特徵?
爲什麼開發人員使用這種模式?

回答

5

這種模式:

sealed trait Controller 
case object Login extends Controller 
case object Logout extends Controller 

或者這

sealed trait Expression 
case class Number(num: Int) extends Expression 
case class Plus(a: Expression, b: Expression) extends Expression 
case class Minus(a: Expression, b: Expression) extends Expression 

被稱爲algebraic data types。他們是創建co-product/sum types(也被稱爲標記聯盟)的斯卡拉方式。當您在簽名中收到類型Expression的特徵時,您知道您將收到具體實現之一。您發現哪種類型是具體類型的方式是通過pattern matching,這是匹配類型的能力。越是這樣,編譯器就足夠了sealed trait聰明,知道它的所有底層的具體類型,讓你知道如果你的模式匹配並不詳盡,例如,如果我添加一個Divide類型:

case class Divide(a: Expression, b: Expression) extends Expression 

而且編譯時,編譯器會報錯:

Warning:(18, 48) match may not be exhaustive. 
It would fail on the following input: Divide(_, _) 
     def value(expression: Expression): Int = expression match { 

至於「空類」,我們必須區分兩種類型。一個是case class。 case類是一種在Scala中創建不可變記錄類型的方法,將它們想象成類固醇上的product type。這些是編譯器自動派生實現hashCodeequals的類,並且還增加了當我們通過apply/unapply進行模式匹配時爲我們提供語法糖的方法。例如:

case Number(value) => value 

你看,我們都能夠訪問Number的模式匹配的value場,這怎麼可能?這是可能的,因爲編譯器爲我們提供了一個用於解構案例類的方法unapply

另一個是case object,這是一種在Scala中創建singleton type(正好代表一個值的類型)的方法。由於我們在LoginLogout上沒有任何字段,我們可以創建該類型的單個表示。