Refutability of Patterns
There are two types of patterns: refutable
and irrefutable
. On the premise of type matching, when a pattern may not match the value to be matched, the pattern is referred to as a refutable
pattern; on the contrary, when a pattern always matches the value, the pattern is referred to as an irrefutable
pattern.
The patterns described above are specified as follows:
Constant patterns are refutable
. In the following example, 1
in the first case and 2
in the second case may be different from the value of x
.
func constPat(x: Int64) {
match (x) {
case 1 => "one"
case 2 => "two"
case _ => "_"
}
}
Wildcard patterns are irrefutable
. In the following example, _
can always match the value of x
.
func wildcardPat(x: Int64) {
match (x) {
case _ => "_"
}
}
Binding patterns are irrefutable
. In the following example, the binding pattern a
can always match the value of x
.
func varPat(x: Int64) {
match (x) {
case a => "x = ${a}"
}
}
Tuple patterns are irrefutable
only when each pattern contained in the tuple pattern is irrefutable
. In the following example, (1, 2)
and (a, 2)
may not match the value of x
. Therefore, they are refutable
. (a, b)
can match any value of x
. Therefore, it is irrefutable
.
func tuplePat(x: (Int64, Int64)) {
match (x) {
case (1, 2) => "(1, 2)"
case (a, 2) => "(${a}, 2)"
case (a, b) => "(${a}, ${b})"
}
}
Type patterns are refutable
. In the following example (assuming that Base
is the parent class of Derived
and Base
implements interface I
), the runtime type of x
may be neither Base
nor Derived
. Therefore, both a: Derived
and b: Base
are refutable
.
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"
}
}
Enum patterns are irrefutable
only when the corresponding enum
type has only one constructor with parameters, and each pattern contained in the enum pattern is irrefutable
. For the definitions of E1
and E2
in the following example, A(1)
in the function enumPat1
is refutable
, and A(a)
is irrefutable
; while B(b)
and C(c)
in the function enumPat2
are refutable.
enum E1 {
A(Int64)
}
enum E2 {
B(Int64) | C(Int64)
}
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})"
}
}