標籤:

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的模式匹配要遵循以下三原則

  1. 始終以值作為結果。

  2. 備選項永遠不會掉到下一個case,僅匹配一次,如果有多個匹配項按代碼先後順序為準。

  3. 如果沒有匹配任何項,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的標準類型。這種類型的值有兩種形式。

  1. Some(x)形式,x是實際的值

  2. 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胥昕:高度產品化是軟體定義存儲成功的關鍵 | 愛分析訪談
林俊傑的高音如何用數據描述?
「現有人工智慧都是二流的」

TAG:Scala | 大数据 |