华为仓颉编程语言的表达式及其特点

华为仓颉编程语言的表达式及其特点

仓颉(Cangjie)语言的表达式有一个明显的特点,范围不再局限于传统算术运算,而是扩展到条件表达式、循环表达式等多种类型,每种表达式均有确定的类型和值。

传统基本表达式,如:

let a = 42

let sum = a + 10

let msg = "Hello"

本文不多介绍,下面重点介绍控制流表达式。

仓颉(Cangjie)作为一门融合了现代编程语言设计理念的语言,弱化了传统 "语句" 与 "表达式" 的界限:

• 条件分支 → if-else 表达式

• 循环 → while、for 表达式

• 异常处理 → try 表达式

• 控制转移 → break、continue 也是表达式,类型为 Nothing

这体现了该语言将传统控制结构表达式化的设计理念。但需要特别注意在这方面的差异化处置:

【仅就目前( 2025 年 7 月推出首个长期支持版本(LTS 1.0.0)),华为仓颉编程语言,在传统控制结构表达式化这方面的差异化处置的总结】

if-else 表达式的类型(返回值类型)由分支类型推断(可能是任意类型,包括 Unit 或非 Unit------指的是它们通常用于返回一个有意义的值(如 String、Int 等)。

while、do-while、for 表达式类型(返回值类型)都是 Unit,强调副作用而非返回值。和if-else 表达式不同,仓颉编程语言的while、do-while、for 表达式类型都是 Unit(表示 "无实际值" 的空类型),强调副作用而非返回值。

Unit:表示"有操作但无值",类型安全且可显式使用。

【唯一值:Unit 类型只有一个实例,即 ()(空元组)。它不携带任何数据,仅表示"操作已完成,但无有意义的结果"。

类型安全:与直接忽略返回值不同,仓颉强制要求显式处理 Unit 类型,避免隐式丢弃值导致的潜在错误。】

异常处理 try 表达式‌返回值可能为非 Unit 类型。

break 和 continue 表达式的类型(返回值类型)为 Nothing,表示它们不返回任何值且不会改变程序的控制流之外的状态。

Nothing:表示"无可能返回"(如 break/continue/抛出异常),是所有类型的子类型,用于控制流转移。

刚开始不太好懂,先总体了解之,看完下面展开介绍及例子,就会逐渐明了。

如何运行下面代码,可参见

华为仓颉编程语言简介与快速实验上手图解_仓颉1.0.0示例-CSDN博客

华为仓颉编程语言实践体验-CSDN博客

if-else 表达式

基本形式:

if (条件) {

分支 1

} else {

分支 2

}

也可写为:

if (条件) { 分支1 } else { 分支2 }。

例如:

cpp 复制代码
import std.convert.*

main() {
    print("请输入score的值: ")
    var str: String = readln()
    var score =  Int8.parse(str)

    // if-else 示例
    if (score >= 60) {
        println("及格")
    } else {
        println("不及格")
    }
       
}

测试运行:

特别说明

if-else 表达式的类型由分支类型推断(可能是任意类型,包括 Unit 或非 Unit)。求值规则:

计算"条件"表达式的值,若为 true,则执行"分支1";若为 false 且存在 else 分支,则执行"分支2"。例如:

cpp 复制代码
import std.convert.*

main() {
    print("请输入a的值: ")
    var str: String = readln()
    var a =  Int64.parse(str)

    print("请输入b的值: ")
    var str2: String = readln()
    var b =  Int64.parse(str2)

    println("max = ${if (a >= b) { a } else { b }}")  //注意这一句,相当于下面两句
    
    let max = if (a >= b) { a } else { b }  //注意这一句
    println("max = ${max}")

}

测试运行

循环:while 、do-while 、for 表达式

while、do-while、for 表达式的类型都是 Unit,强调副作用而非返回值。后面以for 表达式为例特别说明。

while 表达式

基本形式

while (条件) {

循环体

}

例如:

cpp 复制代码
main() {
    var i = 0  
    var sum = 0  
           
    while (i < 10) {  // 调整条件,确保累加1~10
        i += 1
        sum += i       
    }
    println("输出: sum = ${sum}") //输出: sum = 55
    return 0
}

do-while 表达式

基本形式:

do {

循环体

} while (条件)

例如:

cpp 复制代码
main() {
    var i = 1
    do {
        println("Current value: ${i}") 
        i += 1                     
    } while (i <= 3)               
}

输出:

Current value: 1
Current value: 2
Current value: 3

for-in 表达式

基本形式:

for (迭代变量 in 序列) {

循环体

}

例如

cpp 复制代码
main() {
    var sum = 0
    for (i in 1..=100) {
        sum += i
    }
    println("sum = ${sum}")  //sum = 5050
}

前面提到while 、do-while 、for 表达式类型都是 Unit **,强调副作用而非返回值。什么意思?**for 循环表达式为例说明,请看下面例子:

cpp 复制代码
main() {
    var sum = 0
    
    println("sum = ${for (i in 1..=100) { sum += i }}")
}

你可能想,预期通过 for 循环表达式计算 1 + 2 + ... + 100 的和(5050),然后通过字符串模板 ${...} 输出 sum = 5050。

但是实际输出sum = (),而不是sum = 5050 ,问什么?

解释

for循环作为表达式,其默认返回值类型是Unit(表示 "无实际值" 的空类型),无论循环体内做了什么操作。

代码中for (i in 1..=100) { sum += i }的作用是修改外部变量sum(这是一种 "副作用"),但循环本身的返回值始终是Unit。

当你在字符串模板中使用${for (...) {}}时,实际插入的是Unit类型的默认表示形式(),因此输出sum = ()。

你打印的是循环表达式的返回值(Unit),而不是sum变量的值。要打印sum变量的值,可参见前面的示例。

异常处理:try 表达式

基本形式:

try {

// 可能出现异常的代码

} catch (e: ExceptionType) {

// 处理异常的代码

} finally {

// 资源释放的代码(可选)

}

try 块:执行可能抛出异常的代码。

catch 块:捕获异常并返回一个备用值(确保表达式始终有返回值)。

finally 块(可选):执行清理操作,但不影响 try 表达式的返回值。

、判断用户给出的整数的奇偶性,用try异常处理,防止用户输入非数字将出错中断运行,源码如下:

cpp 复制代码
import std.convert.*
import std.io.*
 
main(){
    print("请输入一个整数:")
 
    while (true) {
        var str: String = readln()
      
        if (str.isEmpty()) {
            print("输入为空,请重新输入一个整数:")
            continue
        }
 
        // 使用 try-catch 捕获 parse 可能抛出的异常
        try {
            var n =  Int64.parse(str)
 
            if( n % 2 == 0) {
                println("${n} 是偶数")
            } else {
                println("${n} 是奇数")
            }
            break
        } catch(e:IllegalArgumentException){
            print("输入非法,请输入一个有效的整数:")
        }
    }
 }

特别提示

异常处理 try 表达式‌返回值可能为非 Unit 类型

在华为仓颉编程语言中,try 表达式的返回值类型由 try 块或 catch 块中的最后一行表达式决定。若这些分支返回非 Unit 类型的值,则整个 try 表达式的类型会推断为该具体类型。

例如:

cpp 复制代码
main() {
    // 示例1:try和catch都返回Int类型
    let result1 = try {
        let x = 10
        let y = 2
        x / y  // 返回Int
    } catch (e: Exception) {
        println("发生错误: ${e.message}")
        0  // 返回Int
    }
    println("结果1: ${result1}")  // 输出: 结果1: 5

    // 示例2:try返回String,catch返回String
    let result2 = try {
        "成功执行"  // 返回String
    } catch (e: Exception) {
        "执行失败"  // 返回String
    }
    println("结果2: ${result2}")  // 输出: 结果2: 成功执行

    // 示例3:try抛出异常,catch返回非Unit类型
    let result3 = try {
        throw Exception("故意抛出异常")
        //println("不会执行到这里")
    } catch (e: Exception) {
        "捕获到故意抛出异常"  // 返回String
    }
    println("结果3: ${result3}")  // 输出: 结果3: 捕获到异常
}

测试运行:

这个示例展示了try表达式在不同情况下的返回值类型推断。当try或catch块最后一行是非Unit类型表达式时,整个try表达式就会采用该类型。

控制转移:break 、continue 表达式

break 和 continue 表达式的类型为 Nothing,表示它们不返回任何值且不会改变程序的控制流之外的状态。

【Nothing 是一种特殊的类型,它不包含任何值,并且 Nothing 类型是所有类型的子类型(这当中也包括 Unit 类型)

break、continue、return 和 throw 表达式的类型是 Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行。return 只能在函数体中使用,break、continue 只能在循环体中使用。】

例、以下程序使用 for-in 表达式和 break 表达式,在给定的整数数组中,找到第一个能被 5 整除的数字,源码如下:

cpp 复制代码
main() {
    let numbers = [12, 18, 25, 36, 49, 55]
    for (number in numbers) {
        if (number % 5 == 0) {
            println(number)
            break
        }
    }
}

、以下程序使用 for-in 表达式和 continue 表达式,将给定整数数组中的奇数打印出来,源码如下:

cpp 复制代码
main() {
    let numbers = [12, 18, 25, 36, 49, 55]
    for (number in numbers) {
        if (number % 2 == 0) {
            continue
        }
        println(number)
    }
}
输出:

输出:

25
49
55

、官网介绍

https://cangjie-lang.cn/docs?url=%2F1.0.0%2Fuser_manual%2Fsource_zh_cn%2Fbasic_programming_concepts%2Fexpression.html

相关推荐
蚊子爱喝水1 天前
HUAWEI Pura80系列机型参数对比
人工智能·华为
KK爱Coding2 天前
华为7月23日机考真题
算法·华为
熬了夜的程序员2 天前
【华为机试】547. 省份数量
算法·华为·矩阵·golang·深度优先
生如夏花℡2 天前
HarmonyOS学习记录5
学习·华为·harmonyos
time never ceases2 天前
鸿蒙卡片开发保姆级教程
华为·harmonyos·卡片·harmonyosnext
_waylau2 天前
跟老卫学HarmonyOS开发:HarmonyOS ArkTS 获取位置服务
华为·开源·harmonyos·鸿蒙
ajassi20002 天前
开源 Arkts 鸿蒙应用 开发(十)通讯--Http数据传输
linux·华为·开源·harmonyos
卜锦元2 天前
华为高斯Gauss数据库版本与兼容协议--详解(附带Gorm连接示例代码)
数据库·mysql·华为·postgresql
大数据在线3 天前
“闪存普惠”如何一步到位? 华为在商业市场破题
华为·全闪存储·oceanstor·极简全闪数据中心·华为数据存储