1. Sealed Class
1.1 sealed class
先上一段代碼,看看sealed是怎么使用的
scala> sealed abstract class Drawing
defined class Drawing
scala> case class Point(x: Int, y: Int) extends Drawing
defined class Point
scala> case class Circle(p: Point, r: Int) extends Drawing
defined class Circle
scala> case class Cylinder(c: Circle, h: Int) extends Drawing
defined class Cylinder
scala> def what(d: Drawing) = d match {
| case Point(_,_) => "點(diǎn)"
| case Circle(_,_) => "圓"
| }
<console>:16: warning: match may not be exhaustive.
It would fail on the following input: Cylinder(_, _)
def what(d: Drawing) = d match {
^
what: (d: Drawing)String
在這里what()方法報(bào)錯(cuò)了了赌,主要是因?yàn)檫€缺少了對(duì)Cylinder的匹配巩那,只要改成如下的代碼就可以正常運(yùn)行了吏夯。
scala> def what(d: Drawing) = d match {
| case Point(_,_) => "點(diǎn)"
| case Circle(_,_) => "圓"
| case Cylinder(_,_) => "柱"
| }
what: (d: Drawing)String
在使用模式匹配的時(shí)候此蜈,使用 sealed 修飾某個(gè) class 的目的是讓 Scala 知道所有 case 的情況,否則會(huì)編譯報(bào)錯(cuò)噪生。
當(dāng)然裆赵,也有例外的時(shí)候,使用 @unchecked 告訴編譯器可以不用檢查也能編譯通過(guò)跺嗽。
scala> def what(d: Drawing) = (d: @unchecked) match {
| case Point(_,_) => "點(diǎn)"
| case Circle(_,_) => "圓"
| }
what: (d: Drawing)String
還有一點(diǎn)很重要战授,當(dāng)使用 sealed 來(lái)修飾某個(gè) class 時(shí),繼承該類的其他子類需要跟父類在同一文件中桨嫁。
1.2 sealed trait
同樣植兰,先上一段代碼
scala> sealed trait Color
defined trait Color
scala> final case object Red extends Color
defined object Red
scala> final case object Green extends Color
defined object Green
scala> final case object Blue extends Color
defined object Blue
scala> val colors = List(Red,Green,Blue)
colors: List[Product with Serializable with Color] = List(Red, Green, Blue)
可以看到“Product with Serializable with Color”這一句。
case class 會(huì)自動(dòng)繼承兩個(gè)trait:Product 和 Serializable璃吧。
Product Trait 讓 case class 被擴(kuò)展為具有Algebraic Data Type楣导,或者說(shuō)具有產(chǎn)品類型。
Serializable Trait 讓 case class 可以被視為一個(gè)純粹的數(shù)據(jù)畜挨,能夠被序列化筒繁。
如果你想避免看到這個(gè)實(shí)現(xiàn)的細(xì)節(jié),可以提前聲明Color已經(jīng)擴(kuò)展了 Product 和 Serializable 這些 trait朦促。
scala> sealed trait Color extends Product with Serializable
defined trait Color
scala> final case object Red extends Color
defined object Red
scala> final case object Green extends Color
defined object Green
scala> final case object Blue extends Color
defined object Blue
scala> val colors = List(Red, Green, Blue)
colors: List[Color] = List(Red, Green, Blue)
sealed 修飾的 trait 也只能在當(dāng)前文件里面被繼承膝晾。
1.3 sealed abstract 和 abstract class 的區(qū)別
sealed class的所有子類栓始,無(wú)論是否是抽象類务冕,都必須跟 sealed class 在同一個(gè)文件中。
而abstract class并沒(méi)有這樣的規(guī)定幻赚。
2. Enumeration
Scala 中并沒(méi)有枚舉類型禀忆,但是在標(biāo)準(zhǔn)庫(kù)中有scala.Enumeration
÷淠眨可以擴(kuò)展Enumeration類箩退,調(diào)用Value方法來(lái)初始化枚舉中的可能值。
/**
* Created by tony on 2017/4/12.
*/
object Source extends Enumeration {
type Source = Value
//枚舉的定義
val Net, Memory, Disk = Value
}
import Source._
object Data extends App {
def loadData(source: Source){
source match {
case Net => println ("source type is " + source)
case Memory => println ("source type is " + source)
case Disk => println ("source type is " + source)
case _ => println ("unknown type")
}
}
val net = Source(0) // Calls Enumeration.apply
println(loadData(net)) // source type is Net
// 遍歷Source枚舉
for (s <- Source.values)
println(s.id + ":" + s)
}
打印的結(jié)果:
source type is Net
()
0:Net
1:Memory
2:Disk
在定義枚舉值的時(shí)候也可以自定義id和名稱佳谦,Source2重新定義了幾個(gè)枚舉戴涝。
/**
* Created by tony on 2017/4/12.
*/
object Source2 extends Enumeration {
type Source = Value
//枚舉的定義
val Net, Memory, Disk = Value
val Other = Value(10,"other source")
}
object Data2 extends App {
// 遍歷Source枚舉
for (s <- Source2.values)
println(s.id + ":" + s)
}
打印的結(jié)果:
0:Net
1:Memory
2:Disk
10:other source
最終,我們可以得到:
- Scala中的枚舉使用輕量級(jí)Enumeration進(jìn)行實(shí)現(xiàn)
- Scala中的枚舉其實(shí)是一個(gè)伴隨對(duì)象
- Scala中的枚舉沒(méi)有方法重寫功能
- Scala中的枚舉其實(shí)都是Enumeration.Value這個(gè)對(duì)象
總結(jié)
本篇筆記仍然是為了 Scala 模式匹配所做的鋪墊钻蔑。在模式匹配中會(huì)講到Sealed Class啥刻,所以先整理出來(lái)。除了Sealed用法之外咪笑,還整理了Enumeration的相關(guān)用法可帽。
先前的文章:
Scala學(xué)習(xí)筆記(六) Scala的偏函數(shù)和偏應(yīng)用函數(shù)
Scala學(xué)習(xí)筆記(五) 抽象類以及類中的一些語(yǔ)法糖
Scala學(xué)習(xí)筆記(四) 類的初步
Scala學(xué)習(xí)筆記(三)
Scala學(xué)習(xí)筆記(二)
Scala學(xué)習(xí)筆記(一)