Scala 模式匹配、隱式轉換和參數
模式指按照某種結構組織起來的多個元素的集合,是數據結構上用於描述一個結構的組成。
模式匹配是將兩個模式作為輸入,計算模式元素之間語義上的對應關係的過程。
具體的說,有兩個字元串T和S,字元串T為正文,S為模式,要求找出S在正文T中的出現位置。一旦找到,就說明發生了一次匹配。
def doMatch(plant: String): String = plant match {case "Apple" => "Fruit" case "Cabbage" => "Vegetable" case _ => "Other"}doMatch("Apple")//output: FruitdoMatch("Panda")//output: Other
匹配表達式可以被看作是Java風格switch的泛化。不過Scala的模式匹配要遵循以下三原則
- 始終以值作為結果。
- 備選項永遠不會掉到下一個case,僅匹配一次,如果有多個匹配項按代碼先後順序為準。
- 如果沒有匹配任何項,MatchError異常會拋出。(因此樣例代碼中 有case _ => "Other" 匹配項)
匹配種類
統配符匹配
x match { case _ => println("ok")}
常量匹配
val site = "alibaba.com"site match { case "alibaba.com" => println("ok") case _ => None}
變數匹配
var list = List(1,2)list match {case List(x, y) => println(x)case _ => None}
正則匹配
val pattern = ".*(Hello).*".r"I Say Hello to You." match {case msg@pattern(src) => println(msg)case _ => println(None)}
序列匹配
List(1, 2, 3) match {case List(1, 2, 3) => println("ok")case _ => None}
構造器匹配
trait Nodecase class TreeNode(v: String, left: Node, right: Node) extends Nodecase class Tree(root: TreeNode)val tree = Tree(TreeNode("root", TreeNode("left", null, null), TreeNode("right", null, null)))tree.root match {case TreeNode(_, TreeNode("left", _, _), TreeNode("right", null, null)) => println("bingo")case _ => None}
類型匹配
"hello" match {case str: String => println("ok" + str)case _ => None}
變數綁定匹配
trait Nodecase class TreeNode(v: String, left: Node, right: Node) extends Nodecase class Tree(root: TreeNode)val tree = Tree(TreeNode("root", TreeNode("left", null, null), TreeNode("right", null, null)))tree.root match { case TreeNode(_, leftNode@TreeNode("left",_,_), _) => leftNode case _ => None}
元組匹配
val n=18val m="age"(n , m ,None) match {case (18,"age",None) => println("ok")case (18,"age",_) => println("ok")case _ => None}
抽取器匹配
object EMail {def apply(user:String ,domain:String) = user + "@"+domaindef unapply(str:String):Option[(String,String)] = {val parts = str split "@" if (parts.length == 2) Some(parts(0),parts(1)) else None }}val myEMail = "Stanley@neusoft.com"myEMail match {case EMail(user,domain) => println("Im "+user+".")case _ => None}
Option類型
Scala為可選值定義了一個名為Option的標準類型。這種類型的值有兩種形式。
- Some(x)形式,x是實際的值
- None形式,代表缺失值
這種類型對於模式匹配和集合類型時很有價值,可以對不確定是否是null的值進行匹配。
val list = List("one", "two", "three")//match Nonelist.lift(5) match {case Some(x) => println(x)case None => println("None")}//match Some(x)list.lift(1) match {case Some(x) => println(x)case None => println("None")}
隱式轉換和參數
隱式轉換和參數,可以在編寫Scala程序時故意漏掉一些信息,讓編譯器去嘗試在編譯期間自動推導出這些信息來,這種特性可以極大的減少代碼量,忽略那些冗長,過於細節的代碼。
隱式轉換
val x = 3implicit def stringToInt(x:String) = x.toIntx * "2"
字元串「2」會自動轉型成Int。
隱式值、隱式參數
implicit val name="Stanley"implicit def sayHello(implicit name:String): Unit ={ println("Hello "+name)}sayHello//output: Hello StanleysayHello("Bober")//output: Hello Bober
如果無參調用sayhello時,會默認傳遞name變數。
隱式類
implicit class Person(val name:String){ def sayHello = s"Hello, Im $name."}"Stanley".sayHello
時用implict標註類時,能自動轉換作用域內字面量。(使其擁有sayHello方法)
視界
def maxList[T <% Ordered[T]](elements: List[T]): T = elements match { case List() => throw new IllegalArgumentException("empty list!") case List(x) => x case x :: rest => val maxRest= maxList(rest) //Implicitly, convert to (Ordered) if (x > maxRest) x //Implicitly, orderer(x) else maxRest}val list=List(1,2,3,4)maxList(list)//output: 4
可以認為 「T <% Ordered[T]」 是在說,什麼T無所謂,只有T能當作Ordered[T]即可。雖然Int 不是Ordered[Int] 的子類型。但只要Int到Ordered[Int]的隱式轉換可用,仍然可以把List[Int]傳遞給maxList函數。
忠告
隱式操作是功能強大,代碼凝練的Scala特性。但是,會讓代碼變的晦澀難懂。同時,又有作用域和多個隱式轉換混亂的問題。所以,使用隱式特性要慎之又慎。
推薦閱讀:
※10分鐘快速構建能承載海量數據的數字化體驗監控平台
※如何評價《Big Data:大數據時代》這本書?
※XSKY胥昕:高度產品化是軟體定義存儲成功的關鍵 | 愛分析訪談
※林俊傑的高音如何用數據描述?
※「現有人工智慧都是二流的」