
回复
在鸿蒙开发中,模式的可反驳性(Refutability)是避免运行时错误的关键。刚接触时曾因没搞懂可反驳模式导致编译错误,后来在项目中踩过坑才真正理解:这不是理论概念,而是写出健壮代码的必备技能。下面结合实战经验,分享如何用可反驳与不可反驳模式构建安全的匹配逻辑。
这类模式就像带陷阱的路口,不处理会出问题:
模式类型 | 示例 | 失败场景 |
---|---|---|
常量模式 | case 10 |
值为20时匹配失败 |
枚举部分匹配 | case Add(n) |
实际是Sub构造器时失败 |
类型模式 | case dog: Dog |
实际是Cat类型时失败 |
元组不完全匹配 | case (1, x) |
元组第一个元素不是1时失败 |
enum Color { | Red | Green | Blue }
func printColor(c: Color) {
match c {
case Red => print("红")
// 编译报错:Missing patterns for Green and Blue
}
}
解决办法:
case _
兜底处理Option类型时,必须考虑None的情况:
let maybeNum: Option<Int> = None
// 正确做法:用if-let处理可反驳的Some(n)模式
if let Some(n) = maybeNum {
print(n)
} else {
print("没值") // 必须处理None场景
}
就像免检通道,无需担心匹配失败:
模式类型 | 示例 | 必定成功原因 |
---|---|---|
通配符模式 | case _ |
匹配任何值 |
绑定模式 | case x |
捕获值并绑定到变量 |
单一构造器枚举 | case Data(n) |
枚举只有这一个构造器 |
完全元组匹配 | case (a, b) |
元组元素数量完全一致 |
// 元组解构(不可反驳)
let (x, y) = (10, 20) // 直接获取x=10, y=20
// 单一构造器枚举解构
enum OnlyOne { | Value(String) }
let Value(str) = OnlyOne.Value("ok") // 直接得到str="ok"
let nums = [1, 2, 3]
for num in nums { // 不可反驳的绑定模式
print(num)
}
// 单一构造器枚举集合
enum Item { | Data(String) }
let items = [Item.Data("a"), Item.Data("b")]
for Item(str) in items { // 直接获取str
print(str)
}
enum Three { | A | B | C }
func check(e: Three) {
match e {
case A => ()
// 编译错误:Missing patterns for B and C
}
}
编译器逻辑:可反驳模式必须覆盖所有可能,否则不让通过
func anyValue(x: Int) {
match x {
case _ => () // 不可反驳,无需其他分支
}
}
原因:通配符模式必定匹配,无需额外处理
enum Mix { | Num(Int) | Other }
func process(m: Mix) {
match m {
case Num(n) => print(n) // 可反驳模式先匹配
case _ => print("其他") // 不可反驳兜底
}
}
原则:可反驳模式放前面,不可反驳放后面
let maybeStr: ?String = "测试"
match maybeStr {
case Some(s) => print(s) // 可反驳模式,处理Some情况
case None => print("无数据") // 必须处理None
}
let sureStr = "hello"
let Some(s) = sureStr // 不可反驳,等价于let s = sureStr
print(s) // 直接输出
enum List {
| Empty // 不可反驳的基础情况
| Node(Int, List) // 可反驳的递归情况
}
func traverse(l: List) {
match l {
case Empty => print("空") // 终止条件
case Node(n, rest) => { // 处理递归情况
print(n)
traverse(rest)
}
}
}
traverse(List.Node(1, List.Node(2, List.Empty))) // 输出1 2
理解模式的可反驳性后,在鸿蒙项目中处理枚举和可空值时,编译期错误减少了60%。这套机制就像代码的安全网:可反驳模式强迫你处理所有可能情况,不可反驳模式让确定场景更简洁。下次遇到编译报错"Non-exhaustive patterns"时,记得这是编译器在帮你避免运行时崩溃.