在HarmonyOS Next开发中,match表达式是实现模式匹配的核心控制结构。仓颉语言支持带匹配值的match表达式不带匹配值的match表达式,二者在语法结构和应用场景上有显著差异。本文结合文档知识点,解析这两类表达式的核心用法、匹配逻辑及最佳实践。

一、带匹配值的match表达式:精准值驱动的分支控制

带匹配值的match表达式通过待匹配值与模式的逐一比较,实现条件分支逻辑,适用于枚举值判断、数值范围匹配等场景。

1. 基础语法结构

match (匹配值) {
    case 模式1 => 表达式或语句块
    case 模式2 | 模式3 => 表达式或语句块
    // 其他case分支
}
  • 匹配值:可以是任意表达式(如变量、函数返回值)。
  • 模式:支持常量模式、枚举模式、元组模式等多种类型。

2. 执行流程与匹配规则

  1. 按顺序逐个匹配case分支的模式;
  2. 一旦匹配成功(含pattern guard条件为真),执行对应分支代码并退出match
  3. 若所有模式均不匹配,触发编译错误(除非使用通配符_兜底)。

示例:枚举值匹配

enum Color { | Red | Green | Blue }
let c = Color.Green

match (c) {
    case Red => println("红色")
    case Green => println("绿色")  // 匹配成功,输出"绿色"
    case Blue => println("蓝色")
}

3. Pattern Guard的高级过滤

通过where子句添加额外条件,实现更精细的匹配逻辑:

enum Number { | Odd(Int) | Even(Int) }
let num = Number.Odd(7)

match (num) {
    case Odd(n) where n > 5 => println("\(n)是大于5的奇数")  // 匹配成功
    case Odd(n) => println("\(n)是奇数")
    case Even(n) => println("\(n)是偶数")
}

二、不带匹配值的match表达式:条件驱动的逻辑分支

不带匹配值的match表达式通过判断case后的布尔表达式,实现类似多条件if-else的逻辑,适用于复杂条件组合场景。

1. 基础语法结构

match {
    case 布尔表达式1 => 表达式或语句块
    case 布尔表达式2 => 表达式或语句块
    // 其他case分支
}
  • 布尔表达式:可以是变量比较、函数调用等返回Bool的表达式。
  • 特殊语法case _等价于case true,作为默认分支。

2. 执行流程与匹配规则

  1. 按顺序计算每个case后的布尔表达式;
  2. 首个结果为true的分支被执行,随后退出match
  3. 若所有表达式为false且无case _,编译报错。

示例:数值范围判断

let x = 25

match {
    case x < 0 => println("负数")
    case x >= 0 && x < 10 => println("0-9之间")
    case x >= 10 && x < 20 => println("10-19之间")
    case _ => println("20及以上")  // 匹配成功,输出"20及以上"
}

3. 与if-else if的性能对比

match表达式的条件判断顺序与if-else if一致,但语法更简洁,尤其适合多条件分层场景:

// match表达式
match {
    case isNetworkAvailable() && hasPermission() => fetchData()
    case isNetworkAvailable() => showError("权限不足")
    case _ => showError("无网络")
}

// 等价的if-else if结构
if (isNetworkAvailable() && hasPermission()) {
    fetchData()
} else if (isNetworkAvailable()) {
    showError("权限不足")
} else {
    showError("无网络")
}

三、混合场景:两种match表达式的协同应用

在实际开发中,可结合两类match表达式,处理复杂业务逻辑。

1. 先类型匹配,后条件过滤

let value: Any = 105

// 先通过类型模式判断是否为Int
match (value) {
    case n: Int => {
        // 再通过不带值的match判断范围
        match {
            case n < 0 => println("负整数")
            case n < 100 => println("小于100的整数")
            case _ => println("大于等于100的整数")  // 输出"大于等于100的整数"
        }
    }
    case _ => println("非整数类型")
}

2. 枚举值与布尔条件结合

enum UserStatus { | Active | Inactive(Int) }
let status = UserStatus.Inactive(30)

match (status) {
    case Active => println("用户活跃")
    case Inactive(days) => {
        match {
            case days < 7 => println("未活跃小于7天")
            case days < 30 => println("未活跃7-30天")
            case _ => println("未活跃超过30天")  // 输出"未活跃超过30天"
        }
    }
}

四、常见陷阱与最佳实践

1. 带值匹配的穷尽性要求

必须覆盖枚举所有构造器或使用通配符,否则编译报错:

enum E { | A | B | C }
func f(e: E) {
    match (e) {
        case A => ()
        case B => ()
        // 缺少C分支,编译报错:"Non-exhaustive patterns"
    }
}

2. 不带值匹配的条件顺序

确保条件由具体到通用,避免逻辑覆盖:

let x = 50
match {
    case x == 50 => println("等于50")  // 优先匹配具体条件
    case x > 30 => println("大于30")
    case _ => println("其他")
}

3. 避免冗余模式匹配

对于单一条件,优先使用if而非match,提升可读性:

// 反例:过度使用match
let isLogin = true
match {
    case isLogin => println("已登录")
    case _ => println("未登录")
}

// 正例:使用if-else
if (isLogin) {
    println("已登录")
} else {
    println("未登录")
}

总结

HarmonyOS Next的match表达式通过两类模式提供了灵活的逻辑控制能力:

  • 带值匹配适用于基于具体值的精准分支(如枚举、数值);
  • 不带值匹配适用于条件组合判断(如布尔逻辑、范围检查)。

SameX
1 声望2 粉丝