仓颉编程语言青少年基础教程:布尔类型、元组类型
仓颉编程语言青少年基础教程:布尔类型、元组类型
现在介绍仓颉语言中的布尔和元组数据类型。
布尔类型
编程语言中布尔类型提供了逻辑判断的基础。
布尔类型使用 Bool 表示,用来表示逻辑中的真和假。
布尔类型只有两个字面量:true 和 false。
true 和 false 是控制程序功能和状态的二元开关。这是它们最直观、最常见的用途。
示例:
// 返回布尔字面量的函数
func isPositive(num: Int64): Bool {if (num > 0) {return true} else {return false}
}
// 直接返回布尔字面量
func isEven(num: Int64): Bool {return (num % 2 == 0)
}main() { // 使用函数返回值let result1 = isPositive(10) // truelet result2 = isPositive(-5) // falselet result3 = isEven(8) // truelet result4 = isEven(7) // falseprintln("10是正数: ${result1}") // 输出: 10是正数: trueprintln("-5是正数: ${result2}") // 输出: -5是正数: falseprintln("8是偶数: ${result3}") // 输出: 8是偶数: trueprintln("7是偶数: ${result4}") // 输出: 7是偶数: false
}
运行截图:
布尔类型支持的操作符包括:逻辑操作符(逻辑非 !,逻辑与 &&,逻辑或 ||)、部分关系操作符(== 和 !=)、部分复合赋值操作符(&&= 和 ||=)。
示例:
main() {/* 1. 字面量 ------------------------------------------ */let t = truelet f = falseprintln(f) //输出: false/* 2. 逻辑操作符 --------------------------------------- */let notT = !t // falselet and1 = t && true // truelet or1 = f || t // true,若写为let or1 = t || f,因短路求值规则【注】出现警告:unreachable expression(不可达表达式)println("逻辑运算:")println("!t = ${notT}") // 输出:!t = false println("t && true = ${and1}") // 输出:t && true = true println("t || f = ${or1}") // 输出:t || f = true /* 3. 关系操作符(仅 ==、!=) --------------------------- */let eq = t == true // truelet neq = t != false // trueprintln("\n关系运算:")println("t == true -> ${eq}") // 输出:t == true -> trueprintln("t != false -> ${neq}") // 输出:t != false -> true/* 4. 复合赋值操作符(仅 &&=、||=) --------------------- */var b1 = truevar b2 = falseb1 &&= false // 等价于 b1 = b1 && falseb2 ||= true // 等价于 b2 = b2 || trueprintln("\n复合赋值后:")println("b1 = ${b1}") // 输出:b1 = falseprintln("b2 = ${b2}") // 输出: b2 = true
}
【注】短路求值(short-circuit evaluation)是指:在计算逻辑表达式时,只要前面的值已经能决定整个表达式的结果,后面的表达式就不再计算,直接返回结果。
表达式 | 何时停止计算 | 原因 |
A && B | 如果 A 为 false | 无论 B 是什么,结果一定是 false |
A || B | 如果 A 为 true | 无论 B 是什么,结果一定是 true |
元组(Tuple)
元组类型则提供了一种灵活、类型安全的方式来组合和处理多个不同类型的值。
元组(Tuple)可以将多个不同的类型组合在一起,成为一个新的类型。例如:
// 二元组示例
let coordinates: (Float64, Float64) = (40.7128, -74.0060)
// 三元组示例(自动类型推断)
let userInfo = ("Alice", 34, true) // 推断为(String, Int, Bool)
// 带显式类型标注的元组
let x: (Int64, Float64) = (3, 3.141592)
let y: (Int64, Float64, String) = (3, 3.141592, "PI")
元组类型使用 (T1, T2, ..., TN) 表示,其中 T1 到 TN 可以是任意类型,不同类型间使用逗号(,)连接。元组至少是二元。
元组类型的字面量使用 (e1, e2, ..., eN) 表示,其中 e1 到 eN 是表达式,多个表达式之间使用逗号分隔。
元组支持通过 t[index] 的方式访问某个具体位置的元素,其中 t 是一个元组,index 是下标,并且 index 只能是从 0 开始且小于元组元素个数的整数类型字面量,否则编译报错。
示例:
main() {let serverStatus = (200, "OK", true)println(serverStatus[0]) // 输出: 200println(serverStatus[1]) // 输出: "OK"println(serverStatus[2]) // 输出: true// 错误示例:索引越界// println(serverStatus[3]) // 编译错误
}
元组的长度是固定的,即一旦定义了一个元组类型的实例,它的长度不能再被更改。
元组类型是不可变类型,即一旦定义了一个元组类型的实例,它的内容(即单个元素)不能再被更新。但整个元组可被覆盖替换。
也就是说:
1.元组 = 把 N 个任意类型的值绑在一起
例:(String, Int64, Bool) 就是一个三元组类型。
字面量:("仓颉", 1, true)。
2.长度、元素内容固定
• 你不能往 (A,B,C) 里再塞第 4 个元素。
• 也不能把 "仓颉" 改成 "Rust";想改只能重新建一个元组。
3.变量本身可重新赋值
变量可以整个换掉,但不能单独改里面的某个元素。——元组像“标签贴死的小盒子”,盒子里东西不能换,但你可以把整盒扔掉再拿一个新盒。
示例:
main() {// 1. 定义一个三元组let t: (String, Int64, Bool) = ("仓颉", 42, true)// 2. 取元素值:下标或解构let (name, age, flag) = tprintln("${name} ${age} ${flag}")// 3.下行编译不过println(t[0])// t[0] = "Rust" ❌ 元素不可变// 4.也可以这样定义一个元组,输出其元素let t2 = ("Rust", 10, false)println("t2[0]=${t2[0]}, t2[1]=${t2[1]} ,t2[2]=${t2[2]} ")
}
在赋值表达式中,可使用元组进行多赋值。
示例:
main() {let (statusCode, message, isSuccess) = (200, "OK", true)println("Status: ${statusCode}, message: ${message}, Success: ${isSuccess}") // 输出: Status: 200 , message: OK, Success: true// 部分解构(使用下划线忽略不需要的值)let (_, msg, _) = (200, "OK", true)println("Message: ${msg}") // 输出: Message: OK
}
元组类型的类型参数
可以为元组类型标记显式的类型参数名。需要注意,所有元素的类型都添加参数名,或者所有元素的类型都不添加,不允许部分有、部分没有。
错误示例:
let a: (name: String, Int64) = ("banana", 5)
这里第一个元素的类型有参数名 name,但第二个元素的类型 Int64 没有参数名,违反了 “统一” 规则,因此报错。
正确示例:let b: (name: String, price: Int64) = ("banana", 5)
两个元素的类型都添加了参数名(name 和 price),符合 “统一” 规则,因此合法。
带类型参数名的元组在函数返回值中的用法。
示例:
// 定义一个返回带类型参数名元组的函数:获取用户信息
func getUserInfo(): (username: String, age: Int32, isStudent: Bool) {// 返回具体的元组值,顺序与类型参数名一一对应return ("Alice", 22, true)
}// 主函数中调用并使用该返回值
main() {// 调用函数,接收带类型参数名的元组返回值let user = getUserInfo()// 访问元组元素:必须通过位置索引(而非类型参数名)println("用户名:${user[0]}") // 输出:用户名:Aliceprintln("年龄:${user[1]}") // 输出:年龄:22println("是否学生:${user[2]})") // 输出:是否学生:true
}