HarmonyOS 鸿蒙原生应用元服务开发-仓颉基本概念表达式(一) (原标题已包含“鸿蒙”关键词,故直接加上“HarmonyOS”以符合要求,同时保持语句通顺。)

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙原生应用元服务开发-仓颉基本概念表达式(一)

(原标题已包含“鸿蒙”关键词,故直接加上“HarmonyOS”以符合要求,同时保持语句通顺。)

在一些传统编程语言中,一个表达式由一个或多个操作数(operand)通过零个或多个操作符(operator)组合而成,表达式总是隐含着一个计算过程,因此每个表达式都会有一个计算结果,对于只有操作数而没有操作符的表达式,其计算结果就是操作数自身,对于包含操作符的表达式,计算结果是对操作数执行操作符定义的计算而得到的值。在这种定义下的表达式也被称为算术运算表达式。

在仓颉编程语言中,我们简化并延伸了表达式的传统定义——凡是可求值的语言元素都是表达式。因此,仓颉不仅有传统的算术运算表达式,还有条件表达式、循环表达式和 try 表达式等,它们都可以被求值,并作为值去使用,如作为变量定义的初值和函数实参等。此外,因为仓颉是强类型的编程语言,所以仓颉表达式不仅可求值,还有确定的类型。

仓颉编程语言的各种表达式将在后续章节中逐一介绍,本节介绍最常用的条件表达式、循环表达式以及部分控制转移表达式(break、continue)。

我们知道,任何一段程序的执行流程,只会涉及三种基本结构——顺序结构、分支结构和循环结构。实际上,分支结构和循环结构,是由某些指令控制当前顺序执行流产生跳转而得到的,它们让程序能够表达更复杂的逻辑,在仓颉中,这种用来控制执行流的语言元素就是条件表达式和循环表达式。

在仓颉编程语言中,条件表达式分为 if 表达式和 if-let 表达式两种,它们的值与类型需要根据使用场景来确定。循环表达式有四种:for-in 表达式、while 表达式、do-while 表达式和 while-let 表达式,它们的类型都是 Unit、值为 ()。其中 if-let 表达式和 while-let 表达式都与模式匹配相关

在仓颉程序中,由一对大括号“{}”包围起来的一组表达式,被称为“代码块”,它将作为程序的一个顺序执行流,其中的表达式将按编码顺序依次执行。如果代码块中有至少一个表达式,我们规定此代码块的值与类型等于其中最后一个表达式的值与类型,如果代码块中没有表达式,规定这种空代码块的类型为 Unit、值为 ()。

注意代码块本身不是一个表达式,不能被单独使用,它将依附于函数、条件表达式和循环表达式等执行和求值。

一、if 表达式

if 表达式的基本形式为:

if (条件) {

  分支 1

} else {

  分支 2

}

其中“条件”是布尔类型表达式,“分支 1”和“分支 2”是两个代码块。if 表达式将按如下规则执行:

计算“条件”表达式,如果值为 true 则转到第 2 步,值为 false 则转到第 3 步。

执行“分支 1”,转到第 4 步。

执行“分支 2”,转到第 4 步。

继续执行 if 表达式后面的代码。

在一些场景中,我们可能只关注条件成立时该做些什么,所以 else 和对应的代码块是允许省略的。

如下程序演示了 if 表达式的基本用法:

import std.random.*

main() { let number: Int8 = Random().nextInt8() println(number) if (number % 2 == 0) { println(“偶数”) } else { println(“奇数”) } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

在这段程序中,我们使用仓颉标准库的 random 包生成了一个随机整数,然后使用 if 表达式判断这个整数是否能被 2 整除,并在不同的条件分支中打印“偶数”或“奇数”。

仓颉编程语言是强类型的,if 表达式的条件只能是布尔类型,不能使用整数或浮点数等类型,和 C 语言等不同,仓颉不以条件取值是否为 0 作为分支选择依据,例如以下程序将编译报错:

main() {
let number = 1
if (number) { // Error, mismatched types
println(“非零数”)
}
}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

在许多场景中,当一个条件不成立时,我们可能还要判断另一个或多个条件、再执行对应的动作,仓颉允许在 else 之后跟随新的 if 表达式,由此支持多级条件判断和分支执行,例如:

import std.random.*

main() { let speed = Random().nextFloat64() * 20.0 println("${speed} km/s") if (speed > 16.7) { println(“第三宇宙速度,鹊桥相会”) } else if (speed > 11.2) { println(“第二宇宙速度,嫦娥奔月”) } else if (speed > 7.9) { println(“第一宇宙速度,腾云驾雾”) } else { println(“脚踏实地,仰望星空”) } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

if 表达式的值与类型,需要根据使用形式与场景来确定:

当含 else 分支的 if 表达式被求值时,需要根据求值上下文确定 if 表达式的类型:

如果上下文明确要求值类型为 T,则 if 表达式各分支代码块的类型必须是 T 的子类型,这时 if 表达式的类型被确定为 T,如果不满足子类型约束,编译会报错。

如果上下文没有明确的类型要求,则 if 表达式的类型是其各分支代码块类型的最小公共父类型,如果最小公共父类型不存在,编译会报错。

如果编译通过,则 if 表达式的值就是所执行分支代码块的值。

如果含 else 分支的 if 表达式没有被求值,在这种场景里,开发者一般只想在不同分支里做不同操作,不会关注各分支最后一个表达式的值与类型,为了不让上述类型检查规则影响这一思维习惯,仓颉规定这种场景下的 if 表达式类型为 Unit、值为 (),且各分支不参与上述类型检查。

对于不含 else 分支的 if 表达式,由于 if 分支也可能不被执行,所以我们规定这类 if 表达式的类型为 Unit、值为 ()。

例如,以下程序基于 if 表达式求值,模拟一次简单的模数转换过程:

main() {
let zero: Int8 = 0
let one: Int8 = 1
let voltage = 5.0
let bit = if (voltage < 2.5) {
zero
} else {
one
}
}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

在以上程序中,if 表达式作为变量定义的初值使用,由于变量 bit 没有被标注类型、需要从初值中推导,所以 if 表达式的类型取为两个分支代码块类型的最小公共父类型,根据前文对“代码块”的介绍,可知两个分支代码块类型都是 Int8,所以 if 表达式的类型被确定为 Int8,其值为所执行分支即 else 分支代码块的值,所以变量 bit 的类型为 Int8、值为 1。

二、while 表达式

while 表达式的基本形式为:

while (条件) {

  循环体

}

其中“条件”是布尔类型表达式,“循环体”是一个代码块。while 表达式将按如下规则执行:

计算“条件”表达式,如果值为 true 则转第 2 步,值为 false 转第 3 步。

执行“循环体”,转第 1 步。

结束循环,继续执行 while 表达式后面的代码。

例如,以下程序使用 while 表达式,基于二分法,近似计算数字 2 的平方根:

main() {
var root = 0.0
var min = 1.0
var max = 2.0
var error = 1.0
let tolerance = 0.1 ** 10

<span class="hljs-keyword"><span class="hljs-keyword">while</span></span> (error ** <span class="hljs-number"><span class="hljs-number">2</span></span> &gt; tolerance) {
    root = (min + max) / <span class="hljs-number"><span class="hljs-number">2.0</span></span>
    error = root ** <span class="hljs-number"><span class="hljs-number">2</span></span> - <span class="hljs-number"><span class="hljs-number">2.0</span></span>
    <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (error &gt; <span class="hljs-number"><span class="hljs-number">0.0</span></span>) {
        max = root
    } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
        min = root
    }
}
println(<span class="hljs-string"><span class="hljs-string">"2 的平方根约等于:${root}"</span></span>)

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

运行以上程序,将输出:

2 的平方根约等于:1.414215

资料来源:HarmonyOS Developer 官方网站

1 回复

在HarmonyOS鸿蒙原生应用开发中,仓颉基本概念表达式是元服务开发的核心之一,它用于定义和管理服务间的数据流动与交互。仓颉表达式通过一套高效的数据模型,实现了服务的解耦与动态配置,提升了应用的可扩展性和灵活性。开发者需深入理解其语法与逻辑,以便在元服务设计中灵活运用。如果问题依旧没法解决请加我微信,我的微信是itying888。

回到顶部