Standard patterns
Literal patterns: 字面值模式
字面值模式匹配一个特殊的值,Scala中除了primitive值,Strings,nulls和() 都可以使用:
(1 + 1) match {
case 1 => "It's one!"
case 2 => "It's two!"
case 3 => "It's three!"
}
// res: String = It's two!
Person("Dave", "Gurnell") match {
case Person("Noel", "Welsh") => "It's Noel!"
case Person("Dave", "Gurnell") => "It's Dave!"
}
// res: String = It's Dave!
println("Hi!") match {
case () => "It's unit!"
}
// Hi!
// res: String = It's unit!
Constant patterns: 常量模式
标示符以大写字母开始的叫做常量,用以匹配一个预定义的常量:
val X = "Foo"
// X: String = Foo
val Y = "Bar"
// Y: String = Bar
val Z = "Baz"
// Z: String = Baz
"Bar" match {
case X => "It's foo!"
case Y => "It's bar!"
case Z => "It's baz!"
}
// res: String = It's bar!
Alternative patterns: 选择模式
“|” 竖线用于选择模式:
"Bar" match {
case X | Y => "It's foo or bar!" // X 或 Y
case Z => "It's baz!"
}
// res: String = It's baz!
Variable capture: 变量捕获
小写字母开都的标识符用于绑定值,绑定后该变量可以在 => 右侧使用:
Person("Dave", "Gurnell") match {
case Person(f, n) => f + " " + n
}
// res: String = "Dave Gurnell"
@ 操作符,写作 x @ y,支持我们将值捕获到x中,同时有满足模式y,x必须是一个变量模式(即标示符小写),y可以是任何模式:
Person("Dave", "Gurnell") match {
case p @ Person(_, s) => s"The person $p has the surname $s"
}
// res: String = "The person Person(Dave,Gurnell) is called Dave Gurnell"
即将 @ 后面的整个 Person(, s) 起了个别名p,同时 Person(, s)作为匹配的模式.
Wildcard patterns: 通配符模式
符号 “_” 用于匹配任何值并忽略,在两种场景中比较有用:一种是在别的模式中进行嵌套,另一种是用于匹配任何剩余的分支:
Person("Dave", "Gurnell") match {
case Person("Noel", _) => "It's Noel!"
case Person("Dave", _) => "It's Dave!"
}
// res: String = It's Dave!
Person("Dave", "Gurnell") match {
case Person(name, _) => s"It's $name!"
}
// res: String = It's Dave!
Person("John", "Doe") match {
case Person("Noel", _) => "It's Noel!"
case Person("Dave", _) => "It's Dave!"
case _ => "It's someone else!"
}
// res: String = It's someone else!
Type patterns: 类型模式
类型模式写作 x: Y ,Y是一个类型,x是一个通配符模式或变量模式,该模式将匹配任何符合类型的值并将值绑定到x:
val shape: Shape = Rectangle(1, 2)
// shape: Shape = Rectangle(1.0,2.0)
shape match {
case c : Circle => s"It's a circle: $c!"
case r : Rectangle => s"It's a rectangle: $r!"
case s : Square => s"It's a square: $s!"
}
// res: String = It's a rectangle: Rectangle(1.0,2.0)!
Tuple patterns: 元组模式
(1, 2) match {
case (a, b) => a + b
}
// res: Int = 3
Guard expressions: 守卫表达式
123 match {
case a if a % 2 == 0 => "even"
case _ => "odd"
}
// res: String = odd
Custom Patterns
Extractors
Case class extractors,case类自身伴生对象中自带的解析器:
Person("Dave", "Gurnell") match {
case Person(f, l) => List(f, l)
}
// res: List[String] = List(Dave, Gurnell)
Regular expressions:
import scala.util.matching.Regex
val r = new Regex("""(\d+)\.(\d+)\.(\d+)\.(\d+)""")
// r: scala.util.matching.Regex = (\d+)\.(\d+)\.(\d+)\.(\d+)
"192.168.0.1" match {
case r(a, b, c, d) => List(a, b, c, d)
}
// res: List[String] = List(192, 168, 0, 1)
Lists and Sequences:
List(1, 2, 3) match {
case List(a, b, c) => a + b + c
}
// res: Int = 6
Nil匹配一个空列表:
Nil match {
case List(a) => "length 1"
case Nil => "length 0"
}
// res: String = length 0
单例对象 :: 用于匹配列表的head和tail:
List(1, 2, 3) match {
case ::(head, tail) => s"head $head tail $tail"
case Nil => "empty"
}
// res: String = head 1 tail List(2, 3)
或者:
List(1, 2, 3) match {
case head :: tail => s"head $head tail $tail"
case Nil => "empty"
}
// res: String = head 1 tail List(2, 3)
组合使用::, Nil 和 _ 可以用于匹配任意长度的列表:
List(1, 2, 3) match {
case Nil => "length 0"
case a :: Nil => s"length 1 starting $a"
case a :: b :: Nil => s"length 2 starting $a $b"
case a :: b :: c :: _ => s"length 3+ starting $a $b $c"
}
// res: String = length 3+ starting 1 2 3
自定义一个解析器:
object Email {
def unapply(str: String): Option[(String, String)] = {
val parts = str.split("@")
if (parts.length == 2) Some((parts(0), parts(1))) else None
}
}
"dave@underscore.io" match {
case Email(user, domain) => List(user, domain)
}
// res: List[String] = List(dave, underscore.io)
"dave" match {
case Email(user, domain) => List(user, domain) case _ => Nil
}
// res: List[String] = List()
类似的用法用于匹配任何字符串并转换为大写:
object Uppercase {
def unapply(str: String): Option[String] = Some(str.toUpperCase)
}
Person("Dave", "Gurnell") match {
case Person(f, Uppercase(l)) => s"$f $l"
}
// res: String = Dave GURNELL
Wildcard sequence patterns: 通配符序列模式
List(1, 2, 3, 4, 5) match {
case List(a, b, _*) => a + b
}
// res: Int = 3
"the quick brown fox" match {
case Words(a, b, _*) => a + b
}
// res: String = "thequick"
将剩余元素绑定到一个变量:
"the quick brown fox" match {
case Words(a, b, rest @ _*) => rest
}
// res: Seq[String] = WrappedArray("brown", "fox")