##仓颉##
仓颉语言提供两种强大的 match
表达式:含匹配值和不含匹配值的形式。本文将详细解析其语法、执行逻辑和类型规则,辅以代码示例说明。
一、含匹配值的 match
表达式
语法结构:
match (待匹配表达式) {
case 模式1 | 模式2 where 条件 => { 代码块 }
case _ => { 默认操作 }
}
核心特性:
-
模式匹配:
- 支持常量、枚举、通配符等模式(
_
匹配任意值) |
实现多模式并联:case 1 | 2 => ...
where
添加守卫条件(如case x where x > 0 => ...
)
- 支持常量、枚举、通配符等模式(
-
执行逻辑:
- 自上而下依次匹配,成功即执行对应分支并退出
- 穷尽性检查:必须覆盖所有可能值(编译器强制验证)
- 分支内可定义局部变量(作用域限于当前分支)
示例:
enum RGBColor { | Red(Int16) | Green(Int16) | Blue(Int16) }
main() {
let c = RGBColor.Green(-100);
match (c) {
case Red(r) where r >= 0 => print("Red = ${r}")
case Red(_) => print("Red = 0") // 负值处理
case Green(g) where g >= 0 => print("Green = ${g}")
case Green(_) => print("Green = 0") // 匹配此行
case Blue(b) where b >= 0 => print("Blue = ${b}")
case Blue(_) => print("Blue = 0")
}
}
// 输出:Green = 0
穷尽性验证(编译报错示例):
func nonExhaustive(x: Int64) {
match (x) {
case 0 => print("x=0")
case 1 => print("x=1") // 错误!未覆盖x≠0,1的情况
}
}
二、不含匹配值的 match
表达式
语法结构:
match {
case 条件表达式1 => { 代码块 }
case _ => { 默认操作 } // 等价 case true => ...
}
核心特性:
- 本质是模式化的条件分支,
case
后接布尔表达式 _
分支等价于case true
(兜底分支)- 执行首个条件为
true
的分支
示例:
main() {
let x = -1;
match {
case x > 0 => print("x>0")
case x < 0 => print("x<0") // 匹配此行
case _ => print("x=0")
}
}
// 输出:x<0
三、类型推断规则
match
表达式的类型由上下文和分支类型共同决定:
场景 | 规则 | 示例 |
---|---|---|
有明确上下文类型 | 所有分支必须兼容上下文类型 | let s: String = match(x) { case 0 => "a"; ... } |
无明确上下文类型 | 取所有分支类型的最小公共父类型 | let s = match(x) { case true => 1; case false => "2" } // 类型为 Any |
返回值未被使用 | 类型为 Unit ,不要求分支类型一致 | match(x) { case 0 => print(); case _ => 42 } // 合法 |
类型推断示例:
// 示例1:统一分支类型 → String
let s1 = match (2) {
case 0 => "x=0" // String
case _ => "x≠0" // String → 推断为String
}
// 示例2:分支类型不同 → 最小公共父类型
let s2: Any = match (true) {
case true => 100 // Int
case false => "fail" // String → 推断为Any
}
关键总结
- 穷尽性:含匹配值的
match
必须覆盖所有情况(通配符_
是常用解决方案) - 执行顺序:匹配成功立即执行并退出,后续分支被忽略
- 作用域隔离:分支内定义的变量/函数不污染其他分支
- 类型安全:编译器严格检查分支类型兼容性
通过合理运用两种 match
表达式,可大幅提升仓颉代码的简洁性与健壮性,尤其适合枚举处理、状态机转换等场景。
##仓颉##