main() { let x = -10 let y = match (x) { case 0 => "zero" case n => "x is not zero and x = ${n}" // Matched. } println(y) }
说明:
绑定模式会将匹配到的值与 id 进行绑定,在 => 之后可以通过 id 访问其绑定的值
使用 | 连接多个模式时不能使用绑定模式,也不可嵌套出现在其它模式中,否则会报错
4.4 tuple 模式
1 2 3 4 5 6 7 8 9 10
main() { let tv = ("Alice", 24) let s = match (tv) { case ("Bob", age) => "Bob is ${age} years old" case ("Alice", age) => "Alice is ${age} years old" // Matched case (name, 100) => "${name} is 100 years old" case (_, _) => "someone" } println(s) }
open class Base { var a: Int64 public init() { a = 10 } }
class Derived <: Base { public init() { a = 20 } } main() { var d = Derived() var r = match (d) { case b: Base => b.a // Matched. case _ => 0 } println("r = ${r}") }
执行结果
1
r = 20
说明:
类型模式用于判断一个值的运行时类型是否是某个类型的子类型
Base 和 Derived,并且 Derived 是 Base 的子类,Base 的无参构造函数中将 a 的值设置为 10,Derived 的无参构造函数中将 a 的值设置为 20
main() { let command = SetTimeUnit(Year(2022)) match (command) { case SetTimeUnit(Year(year)) => println("Set year ${year}") case SetTimeUnit(Month(month)) => println("Set month ${month}") case _ => () } }
打印结果
1
Set year 2022
说明:
Tuple 模式和 enum 模式可以嵌套任意模式
图示为两种枚举类型组合
五 模式的Refutability
5.1 说明
模式可以分为两类:refutable 模式和 irrefutable 模式
在类型匹配的前提下,当一个模式有可能和待匹配值不匹配时,称此模式为 refutable 模式
反之,当一个模式总是可以和待匹配值匹配时,称此模式为 irrefutable 模式。
5.2 refutable 模式(不匹配)
1-常量模式(下例中第一个 case 中的 1 和第二个 case 中的 2 都有可能和 x 的值不相等)
1 2 3 4 5 6 7
func constPat(x: Int64) { match (x) { case 1 => "one" case 2 => "two" case _ => "_" } }
2-类型模式
1 2 3 4 5 6 7 8 9 10 11
interface I {} open class Base <: I {} class Derived <: Base {}
func typePat(x: I) { match (x) { case a: Derived => "Derived" case b: Base => "Base" case _ => "Other" } }
5.3 irrefutable 模式(匹配)
1-通配符模式(无论 x 的值是多少,_ 总能和其匹配)
1 2 3 4 5
func wildcardPat(x: Int64) { match (x) { case _ => "_" } }
2-绑定模式(无论 x 的值是多少,绑定模式 a 总能和其匹配)
1 2 3 4 5
func varPat(x: Int64) { match (x) { case a => "x = ${a}" } }
3-Tuple 模式(当且仅当其包含的每个模式都是 irrefutable 模式)
1 2 3 4 5 6 7
func tuplePat(x: (Int64, Int64)) { match (x) { case (1, 2) => "(1, 2)" case (a, 2) => "(${a}, 2)" case (a, b) => "(${a}, ${b})" } }
func enumPat1(x: E1) { match (x) { case A(1) => "A(1)" case A(a) => "A(${a})" } }
func enumPat2(x: E2) { match (x) { case B(b) => "B(${b})" case C(c) => "C(${c})" } }
六 常见表达式
6.1 match表达式
1 2 3 4 5 6 7 8 9 10 11
main() { let x = 0 match (x) { case 1 => let r1 = "x = 1" print(r1) case 0 => let r2 = "x = 0" // Matched. print(r2) case _ => let r3 = "x != 1 and x != 0" print(r3) } }