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

鸿蒙时代
发布于 2024-8-9 12:02
浏览
0收藏

三、do-while 表达式
do-while 表达式的基本形式为:
do {
循环体
} while (条件)
其中“条件”是布尔类型表达式,“循环体”是一个代码块。do-while 表达式将按如下规则执行:
执行“循环体”,转第 2 步。
计算“条件”表达式,如果值为 true 则转第 1 步,值为 false 转第 3 步。
结束循环,继续执行 do-while 表达式后面的代码。
例如,以下程序使用 do-while 表达式,基于蒙特卡洛算法,近似计算圆周率的值:

import std.random.*

main() {
    let random = Random()
    var totalPoints = 0
    var hitPoints = 0

    do {
        // 在 ((0, 0), (1, 1)) 这个正方形中随机取点
        let x = random.nextFloat64()
        let y = random.nextFloat64()
        // 判断是否落在正方形内接圆里
        if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {
            hitPoints++
        }
        totalPoints++
    } while (totalPoints < 1000000)

    let pi = 4.0 * Float64(hitPoints) / Float64(totalPoints)
    println("圆周率近似值为:${pi}")
}

运行以上程序,将输出:
圆周率近似值为:3.141872
说明
由于算法涉及随机数,所以每次运行程序输出的数值可能都不同,但都会约等于 3.14。
四、for-in 表达式
for-in 表达式可以遍历那些扩展了迭代器接口 Iterable<T> 的类型实例。for-in 表达式的基本形式为:
for (迭代变量 in 序列) {
循环体
}
其中“循环体”是一个代码块。“迭代变量”是单个标识符或由多个标识符构成的元组,用于绑定每轮遍历中由迭代器指向的数据,可以作为“循环体”中的局部变量使用。“序列”是一个表达式,它只会被计算一次,遍历是针对此表达式的值进行的,其类型必须扩展了迭代器接口 Iterable<T>。for-in 表达式将按如下规则执行:
计算“序列”表达式,将其值作为遍历对象,并初始化遍历对象的迭代器。
更新迭代器,如果迭代器终止,转第 4 步,否则转第 3 步。
将当前迭代器指向的数据与“迭代变量”绑定,并执行“循环体”,转第 2 步。
结束循环,继续执行 for-in 表达式后面的代码。
说明
仓颉内置的区间和数组等类型已经扩展了 Iterable<T> 接口。
例如,以下程序使用 for-in 表达式,遍历中国地支字符构成的数组 noumenonArray,输出农历 2024 年各月的干支纪法:

main() {
    let metaArray = [r'甲', r'乙', r'丙', r'丁', r'戊',
        r'己', r'庚', r'辛', r'壬', r'癸']
    let noumenonArray = [r'寅', r'卯', r'辰', r'巳', r'午', r'未',
        r'申', r'酉', r'戌', r'亥', r'子', r'丑']
    let year = 2024
    // 年份对应的天干索引
    let metaOfYear = ((year % 10) + 10 - 4) % 10
    // 此年首月对应的天干索引
    var index = (2 * metaOfYear + 3) % 10 - 1
    println("农历 2024 年各月干支:")
    for (noumenon in noumenonArray) {
        print("${metaArray[index]}${noumenon} ")
        index = (index + 1) % 10
    }
}

运行以上程序,将输出:
农历 2024 年各月干支:
丙寅 丁卯 戊辰 己巳 庚午 辛未 壬申 癸酉 甲戌 乙亥 丙子 丁丑
1.遍历区间
for-in 表达式可以遍历区间类型实例,例如:

main() {
    var sum = 0
    for (i in 1..=100) {
        sum += i
    }
    println(sum)
}

运行以上程序,将输出:
5050
2.遍历元组构成的序列
如果一个序列的元素是元组类型,则使用 for-in 表达式遍历时,“迭代变量”可以写成元组形式,以此实现对序列元素的解构,例如:

main() {
    let array = [(1, 2), (3, 4), (5, 6)]
    for ((x, y) in array) {
        println("${x}, ${y}")
    }
}

运行以上程序,将输出:
1, 2
3, 4
5, 6
3.迭代变量不可修改
在 for-in 表达式的循环体中,不能修改迭代变量,例如以下程序在编译时会报错:

main() {
    for (i in 0..5) {
        i = i * 10 // Error, cannot assign to value which is an initialized 'let' constant
        println(i)
    }
}

4.使用通配符 _ 代替迭代变量
在一些应用场景中,我们只需要循环执行某些操作,但并不使用迭代变量,这时您可以使用通配符 _ 代替迭代变量,例如:

main() {
    var number = 2
    for (_ in 0..5) {
        number *= number
    }
    println(number)
}

运行以上程序,将输出:
4294967296
注意:在这种场景下,如果您使用普通的标识符定义迭代变量,编译会输出“unused variable”告警,使用通配符 _ 则可以避免这一告警。
5.where 条件
在部分循环遍历场景中,对于特定取值的迭代变量,我们可能需要直接跳过、进入下一轮循环,虽然可以使用 if 表达式和 continue 表达式在循环体中实现这一逻辑,但仓颉为此提供了更便捷的表达方式——可以在所遍历的“序列”之后用 where 关键字引导一个布尔表达式,这样在每次将进入循环体执行前,会先计算此表达式,如果值为 true 则执行循环体,反之直接进入下一轮循环。例如:

main() {
    for (i in 0..8 where i % 2 == 1) { // i 为奇数才会执行循环体
        println(i)
    }
}

运行以上程序,将输出:
1
3
5
7
五、break 与 continue 表达式
在循环结构的程序中,有时我们需要根据特定条件提前结束循环或跳过本轮循环,为此仓颉引入了 break 与 continue 表达式,它们可以出现在循环表达式的循环体中,break 用于终止当前循环表达式的执行、转去执行循环表达式之后的代码,continue 用于提前结束本轮循环、进入下一轮循环。break 与 continue 表达式的类型都是 Nothing。
例如,以下程序使用 for-in 表达式和 break 表达式,在给定的整数数组中,找到第一个能被 5 整除的数字:

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

当 for-in 迭代至 numbers 数组的第三个数 25 时,由于 25 可以被 5 整除,所以将执行 if 分支中的 println 和 break,break 将终止 for-in 循环,numbers中的后续数字不会被遍历到,因此运行以上程序,将输出:
25
以下程序使用 for-in 表达式和 continue 表达式,将给定整数数组中的奇数打印出来:

main() {
    let numbers = [12, 18, 25, 36, 49, 55]
    for (number in numbers) {
        if (number % 2 == 0) {
            continue
        }
        println(number)
    }
}

在循环迭代中,当 number 是偶数时,continue 将被执行,这会提前结束本轮循环、进入下一轮循环,println 不会被执行,因此运行以上程序,将输出:
25
49
55
资料来源:HarmonyOS Developer 官方网站

分类
标签
收藏
回复
举报
回复
    相关推荐