match中每個case均可以單獨提取出來,意思是同樣的.程序員
應用案例正則表達式
val (x, y) = (1, 2) val (q, r) = BigInt(10) /% 3 //說明 q = BigInt(10) / 3 r = BigInt(10) % 3 val arr = Array(1, 7, 2, 9) val Array(first, second, _*) = arr // 提出arr的前兩個元素 println(first, second)
for循環也能夠進行模式匹配.app
應用案例測試
val map = Map("A"->1, "B"->0, "C"->3) for ( (k, v) <- map ) { println(k + " -> " + v) } //說明 for ((k, 0) <- map) { println(k + " --> " + 0) } //說明 for ((k, v) <- map if v == 0) { println(k + " ---> " + v) }
樣例類快速入門優化
abstract class Amount case class Dollar(value: Double) extends Amount case class Currency(value: Double, unit: String) extends Amount case object NoAmount extends Amount 說明: 這裏的 Dollar,Currencry, NoAmount 是樣例類。
基本介紹spa
1)樣例類仍然是類設計
2)樣例類用case關鍵字進行聲明。3d
3)樣例類是爲模式匹配而優化的類rest
4)構造器中的每個參數都成爲val——除非它被顯式地聲明爲var(不建議這樣作)code
5)在樣例類對應的伴生對象中提供apply方法讓你不用new關鍵字就能構造出相應的對象
6)提供unapply方法讓模式匹配能夠工做
7)將自動生成toString、equals、hashCode和copy方法(有點相似模板類,直接給生成,供程序員使用)
8)除上述外,樣例類和其餘類徹底同樣。你能夠添加方法和字段,擴展它們
樣例類最佳實踐1:
當咱們有一個類型爲Amount的對象時,能夠用模式匹配來匹配他的類型,並將屬性值綁定到變量(即:把樣例類對象的屬性值提取到某個變量,該功能有用)
for (amt <- Array(Dollar(1000.0), Currency(1000.0, "RMB"), NoAmount)) { val result = amt match { //說明 case Dollar(v) => "$" + v //說明 case Currency(v, u) => v + " " + u case NoAmount => "" } println(amt + ": " + result) }
樣例類最佳實踐2:
樣例類的copy方法和帶名參數
copy建立一個與現有對象值相同的新對象,並能夠經過帶名參數來修改某些屬性。
val amt = Currency(29.95, "RMB") val amt1 = amt.copy() //建立了一個新的對象,可是屬性值同樣 val amt2 = amt.copy(value = 19.95) //建立了一個新對象,可是修改了貨幣單位 val amt3 = amt.copy(unit = "英鎊")//.. println(amt) println(amt2) println(amt3)
什麼是中置表達式?1 + 2,這就是一箇中置表達式。若是unapply方法產出一個元組,你能夠在case語句中使用中置表示法。好比能夠匹配一個List序列
應用實例
List(1, 3, 5, 9) match { //修改並測試 //1.兩個元素間::叫中置表達式,至少first,second兩個匹配才行. //2.first 匹配第一個 second 匹配第二個, rest 匹配剩餘部分(5,9) case first :: second :: rest => println(first + second + rest.length) // case _ => println("匹配不到...") }
操做原理相似於正則表達式
最佳實踐案例-商品捆綁打折出售
如今有一些商品,請使用Scala設計相關的樣例類,完成商品捆綁打折出售。要求
1)商品捆綁能夠是單個商品,也能夠是多個商品。
2)打折時按照折扣x元進行設計.
3)可以統計出全部捆綁商品打折後的最終價格
建立樣例類
abstract class Item // 項 case class Book(description: String, price: Double) extends Item //Bundle 捆 , discount: Double 折扣 , item: Item* , case class Bundle(description: String, discount: Double, item: Item*) extends Item
匹配嵌套結構(就是Bundle的對象)
//給出案例表示有一捆數,單本漫畫(40-10) +文學做品(兩本書)(80+30-20) = 30 + 90 = 120.0 val sale = Bundle("書籍", 10, Book("漫畫", 40), Bundle("文學做品", 20, Book("《陽關》", 80), Book("《圍城》", 30)))
知識點1-將descr綁定到第一個Book的描述
val sale = Bundle("書籍", 10, Book("漫畫", 40), Bundle("文學做品", 20, Book("《陽關》", 80), Book("《圍城》", 30)))
val res = sale match { //若是咱們進行對象匹配時,不想接受某些值,則使用_ 忽略便可,_* 表示全部 case Bundle(_, _, Book(desc, _), _*) => desc }
知識點2-經過@表示法將嵌套的值綁定到變量。_*綁定剩餘Item到rest
val sale = Bundle("書籍", 10, Book("漫畫", 40), Bundle("文學做品", 20, Book("《陽關》", 80), Book("《圍城》", 30)))
這個嵌套結構中的 "漫畫" 和 紫色的部分 綁定到變量,即賦值到變量中.
val result2 = sale match { case Bundle(_, _, art @ Book(_, _), rest @ _*) => (art, rest) } println(result2) println("art =" + result2._1) println("rest=" + result2._2)
知識點3-不使用_*綁定剩餘Item到rest
val result2 = sale match { //說明由於沒有使用 _* 即明確說明沒有多個Bundle,因此返回的rest,就不是WrappedArray了。 case Bundle(_, _, art @ Book(_, _), rest) => (art, rest) } println(result2) println("art =" + result2._1) println("rest=" + result2._2)