Source From Here
部份函式(Partial function)
在使用模式比對時,所使用的 案例序列(Case sequence)實際上是一種 函式常量(Function literal)寫法。你也可以將之當作函式來使用,例如(一個求 費式數列 的例子):
一般在定義函式時,函式會有一個執行函式本體的進入點(
Entry point),且只會有一個參數列(Parameter list)。案例序列 也是一種 函式常量寫法,只不過這個函式會有多個進入函式本體的點,每個 => 之後相當於一個函式本體,而每個模式比對案例(Case)是進入該函式本體所使用的參數列。既然 案例序列 是一種函式常量寫法,那麼你自然也可以將之傳遞,例如:
Scala 中一個應用的實例,可以在使用
scala.actors.Actor (scala.actors - Actor-based concurrency which is deprecated and replaced by Akka actors, scala-actors.jar) 的方法時看到,例如 Actor 的 receive 方法就接受一個 案例序列 所傳入的函式實字(以下只是示範,之後還會介紹 Actor 的使用):
事實上,案例序列 所定義的是個
部份函式(Partial function),所謂部份函式是語言的一種特性,表示你所宣告的函式對於輸入可能有定義也可能沒有定義。舉個例子來說,下面的函式對於 Point(1, 1)、Point(2, 2) 有定義,但對於其它的 Point 情況該怎麼執行則沒有定義:
如果你想要知道某個部份函式對於某種情況是否有定義,則可以使用
scala.PartialFunction 來宣告,例如:
scala.PartialFunction 有個 isDefinedAt() 方法,可以讓你測試某個案例是否存在,例如:
事實上,當你明確告訴編譯器某個函式為部份函式時,也就是使用
scala.PartialFunction 宣告時,編譯器會替你作類似以下的轉譯動作:
部份函式(Partial function)
在使用模式比對時,所使用的 案例序列(Case sequence)實際上是一種 函式常量(Function literal)寫法。你也可以將之當作函式來使用,例如(一個求 費式數列 的例子):
- val fibonacci: Int => Int = {
- case 0 => 0
- case 1 => 1
- case n => fibonacci(n - 1) + fibonacci(n - 2)
- }
- println(fibonacci(10)) // 55
- sealed abstract class Drawing
- case class Point(x: Int, y: Int) extends Drawing
- case class Circle(p: Point, r: Int) extends Drawing
- case class Cylinder(c: Circle, h: Int) extends Drawing
- class Graphic {
- def show(how: Drawing => Any) = {
- how(Point(1, 1))
- how(Circle(Point(2, 2), 2))
- how(Cylinder(Circle(Point(3, 3), 3), 3))
- }
- }
- val g = new Graphic
- g.show {
- case Point(_, _) => println("點")
- case Circle(Point(_, _), _) => println("圓")
- case Cylinder(Circle(Point(_, _), _), _) => println("柱")
- }
- import scala.actors.Actor._
- val caller = self
- actor {
- caller ! args(0)
- }
- receive {
- case "some" => println("do something...")
- case "other" => println("do other...")
- }
- case class Point(x: Int, y: Int)
- val what: Point => Int = {
- case Point(1, 1) => 1
- case Point(2, 2) => 2
- }
- println(what(Point(1, 1))) // 1
- println(what(Point(2, 2))) // 2
- println(what(Point(3, 3))) // MatchError
- case class Point(x: Int, y: Int)
- val what: PartialFunction[Point, Int] = {
- case Point(1, 1) => 1
- case Point(2, 2) => 2
- }
- if(what.isDefinedAt(Point(1, 1)))
- println(what(Point(1, 1)))
- else
- println("函式沒有定義此情況")
- if(what.isDefinedAt(Point(3, 3)))
- println(what(Point(3, 3)))
- else
- println("函式沒有定義此情況")
- new PartialFunction[Point, Int] {
- def apply(p: Point) = p match {
- case Point(1, 1) => 1
- case Point(2, 2) => 2
- }
- def isDefinedAt(p: Point) = p match {
- case Point(1, 1) => true
- case Point(2, 2) => true
- _ => false
- }
- }
沒有留言:
張貼留言