今天在學習<code>akka</code>的監控策咯過程中看到了下面一段代碼:
當時有點好奇,就想去看看<code>resume</code>, <code>restart</code>等的實作,于是就看到了下面的代碼:
object supervisorstrategy extends supervisorstrategylowpriorityimplicits {
sealed trait directive
剛剛scala不久,不太清楚這裡的<code>sealed</code>關鍵字的作用,本文下面就詳細的描述一下這個關鍵字的作用吧。
模式比對pattern matching在scala裡面是一個重量級的功能,依賴于模式比對可以優雅地實作很多功能。大緻格式如下:
pattern總結起來大約以下幾類:
wildcard patterns // _ 統配
constant patterns // 常量
variable patterns // 變量
constructor patterns // 構造函數
sequence patterns // 比如list(,). 如果需要比對剩餘的話使用list(0,_*)
tuple patterns // (a,b,c)
typed patterns // 使用類型比對 case a:map[,]
asinstanceof[]
isinstanceof[]
note(dirlt):這裡需要注意容器類型擦除.array例外因為這個是java内置類型
實際上我們還能夠使用pattern完成下面事情:
patterns in variable definitions // val (a,b) = ("123","345");
case sequences as partial functions
直接使用pattern來構造函數.以參數為match對象,在body裡面直接編寫case.
each case is an entry point to the function, and the parameters are specified with the pattern. the body of each entry point is the right-hand side of the case.
patterns in for expressions // for ((country, city) <- capitals)
pattern matching過程中還有下面幾個問題需要注意:
patterns are tried in the order in which they are written.
variable binding // 有時候我們希望比對的變量包含外層結構
a(1,b(x)) => handle(b(x))
a(1, p @ b(_)) => handle(p) # p綁定了b(x)這個比對
a(1, p @ b()) => handle(p) # b是可以包含unapply從type(p) => boolean的類,做條件判斷
pattern guards // 有時候我們希望對pattern做一些限制性條件
a(1,e,e) 比如希望後面兩個元素相等,但是這個在pm裡面沒有辦法表達
a(1,x,y) if x == y => // 通過guard來完成
scala為了友善擴充模式比對對象的case, 提供<code>case class</code>這個概念。case class和普通class大緻相同,不過有以下三個差別,定義上隻需要在class之前加上case即可:
提供factory method來友善構造object
class parameter隐含val prefix
自帶tostring,hashcode,equals實作
case class最大就是可以很友善地用來做pattern matching.
如果我們能夠知道某個selector所有可能的pattern的話,那麼就能夠在編譯期做一些安全性檢查。但是selector這個過于寬泛,如果将selector限制在類層次上的話,那麼還是可以實作的。舉例如下:
在match a這個過程中,實際上我們可能存在b,c,d三種子類,但是因為我們這裡缺少檢查。使用sealed關鍵字可以完成這個工作。sealed class必須和subclass在同一個檔案内。a sealed class cannot have any new subclasses added except the ones in the same file. 如果上面增加sealed的話,那麼編譯會出現如下警告,說明我們沒有枚舉所有可能的情況。
有三個方式可以解決這個問題,一個是加上對d的處理,一個是使用unchecked annotation, 一個則是在最後用wildcard比對
從上面的描述我們可以知道,<code>sealed</code> 關鍵字主要有2個作用:
其修飾的trait,class隻能在目前檔案裡面被繼承
用sealed修飾這樣做的目的是告訴scala編譯器在檢查模式比對的時候,讓scala知道這些case的所有情況,scala就能夠在編譯的時候進行檢查,看你寫的代碼是否有沒有漏掉什麼沒case到,減少程式設計的錯誤。