歡迎您光臨本站 註冊首頁

淺談Scala模式匹配

←手機掃碼閱讀     techdo @ 2020-06-30 , reply:0

一.scala模式匹配(pattern matching)

pattern matching可以說是scala中十分強大的一個語言特性,當然這不是scala獨有的,但這不妨礙它成為scala的語言的一大利器。

scala的pattern matching是類似這樣的,

  e match {   case Pattern1 => do Something   case Pattern2 if-clause => do others   ...  }

 

其中,變數e後面接一個match以及一個程式碼塊,其中每個case對應一種可能回匹配的型別,如果匹配成功則執行=>後面的程式碼。

我們可以用一個具體一些的例子來看看模式匹配是怎麼工作的:

  case class Player(name: String, score: Int)  def printMessage(player: Player) = player match {   case Player(_, score) if score > 100000 =>    println("Get a job, dude!")   case Player(name, _) =>    println("Hey, $name, nice to see you again!")  }

 

看起來有點類似於其他語言的switch,但其實還是有很大的不同的。

以java的switch為例,java的switch僅僅會做一些基本型別的匹配,然後執行一些動作,並且是沒有返回值的。

而scala的pattern matching match則要強大得多,除了可以匹配數值,同時它還能匹配型別。

  def parseArgument(arg: String) = arg match {    //匹配值    case "-h" | "--help" => displayHelp    case "-v" | "--version" => displayVerion    case whatever => unknownArgument(whatever)  }

 

  def f(x: Any): String = x match {    //匹配型別    case i:Int => "integer: " + i    case _:Double => "a double"    case s:String => "I want to say " + s  }

 

同時pattern matching是有返回值的,比如上面的match,它返回的就是一個Unit。我們也可以修改上面的程式碼讓它返回一個字串:

  case class Player(name: String, score: Int)  def message(player: Player) = player match {   case Player(_, score) if score > 100000 =>    "Get a job, dude!"   case Player(name, _) =>    "Hey, $name, nice to see you again!"  }

 

值得一提的是,pattern matching 返回值是由第一個匹配的模式中的程式碼塊決定的。

二. 為什麼要用pattern matching
 

看到這裡你會發現一個問題,pattern matching不是和if else差不多嗎?那為什麼還要使用pattern matching呢?

首先我們需要明白,模式匹配其實本質上是提供一個方便的解構(Destructuring)資料結構的方式,以scala為例,pattern matching其實用到了scala中提取器的功能,提取器其實就是類中的unapply()方法。

  trait User {   def name: String  }  class FreeUser(val name: String) extends User  object FreeUser {   //提取器   def unapply(user: FreeUser): Option[String] = Some(user.name)  }

 

   val user: User = new FreeUser("Daniel")   user match {    case FreeUser(name) => println("it match here" + name)    case _ => println("not me")   }

 

明白了模式匹配的本質你就會直到,其實if else只是pattern matching中的一個典型的用法,但並非它的全部。

同時,pattern matching允許你解耦兩個並不真正屬於彼此的東西,也使得你的程式碼更易於測試。比如上面的match部分的程式碼我們可以寫成下面這樣:

   val user: User = new FreeUser("Daniel")   //將返回結果存在一個常量中   val message = user match {    case FreeUser(name) => "it match here" + name    case _ => "not me"   }   //可以隨意使用該常量,實現解耦   println(message)

 

這樣會賦予程式碼更多的靈活性,同時也更加方便做進一步操作。

而以可讀性的角度來說,使用一大堆的if else程式碼無疑是比較難看的,而如果使用pattern matching的話,程式碼會簡潔清晰很多,而簡潔的程式碼則會更容易閱讀。


[techdo ] 淺談Scala模式匹配已經有113次圍觀

http://coctec.com/docs/program/show-post-240443.html