match 类似 switch, 同样具有返回值

val args = Array("chips")
val firstArg = if (args.length >0 ) args(0) else ""
// 无需 break. 
firstArg match {
  case "salt" => println("pepper")
  case "chips" => println("salsa")
  case "eggs" => println("bacon")
  case _ => println("huh?") // _ 等同于 default
} 
import scala.util.Random

object PatternDemo {
  def main(args: Array[String]): Unit = {

    // 常量字面值的匹配
    val site = "baidu.com"
    val SITE1 = "baidu1.com"
    site match {
      case "baidu.com" => println("success")  // 匹配字面值

      case SITE1 => println("const success")  // 匹配常量里的值, 可以正常匹配

      case _ => println("fail")  // default
    }

    // 变量模式匹配
    val site1 = "google.com"
    site match {
      // 如果匹配值是小写,会认为 site1 是一个变量
      // 则总是会执行将 site 的值赋值给 site1, 所以总是能匹配成功
      case site1 => println(s"$site1 success")  // 打印 baidu.com success
      case _ => println("fail")
    }

    // 通配符模式匹配
    val list = List(1, 2, 3)
    list match {
      // 前两个 _ 是占位,第三个元素需要是 3
      case List(_, _, 3) => println("success")
      case _ => println("fail")
    }

    // 样例类匹配
    abstract class Notification
    case class Email(sender: String, title: String, body: String) extends Notification
    case class SMS(caller: String, message: String) extends Notification
    case class VoiceRecording(contactName: String, link: String) extends Notification

    def showNotification(notification: Notification) : Unit = {
      val msg = notification match {
        case Email(sender, title, _) if (sender == "a") => s"you get a email from $sender"
        case SMS(caller, _) => s"you get a sms from $caller"
        case VoiceRecording(contactName, _) => s"you get a VoiceRecording from $contactName"
        case _ => "you get a message"
      }
      println(msg)
    }
    val email: Email = Email("a", "title", "...")
    val email2: Email = Email("b", "title", "...")
    val sms: SMS = SMS("b", "...")
    showNotification(email)
    showNotification(email2)
    showNotification(sms)

    // 类型匹配
    val arr = Array("sss", 1, 2, 3, 'c')
    val obj = arr(Random.nextInt(arr.length-1))  // 随机取一个元素
    println(obj)
    obj match {
      case x: Int => println(x)  // 这里可以匹配并赋值
      case s: String => println(s.toUpperCase)
      case d: Double => println("double")
      case _ => println("fail")
    }
  }
}