琉离铟落的小窝琉离铟落的小窝
← 返回文章列表
2026-06-24
#Cangjie#入门教程

元组类型

仓颉的基本数据类型

2.6.1 什么是元组?

元组(Tuple)可以把多个不同类型的值打包在一起,形成一个新的类型。

你可以把元组想象成一个固定大小的快递箱——箱子里有固定的格子,每个格子可以放不同类型的东西,但格子的数量和位置一旦确定就不能改了。

Cangjie
let person: (String, Int64) = ("仓颉", 3)        // 二元组:名字和版本号
let point: (Float64, Float64, Float64) = (1.0, 2.0, 3.0)  // 三元组:三维坐标
ℹ️NOTE

元组至少是二元的,不存在只有一个元素的元组。


2.6.2 元组的核心特点

特点 说明
长度固定 定义后不能增加或减少元素
不可变 单个元素不能被修改,但整个元组可以被覆盖替换
类型可不同 每个位置可以是不同的类型

不可变的含义

Cangjie
let tuple1 = (8, false)
var tuple2 = (true, 9, 20)
tuple2 = tuple1         // ❌ 报错:类型不匹配,(Int64, Bool) ≠ (Bool, Int64, Int64)
tuple2[0] = false       // ❌ 报错:元组元素不能被单独修改

var tuple3 = (9, true)
tuple3 = tuple1         // ✅ 类型匹配,整个元组被替换
println(tuple3[0])      // 输出 8
println(tuple3[1])      // 输出 false
IMPORTANT

元组不可变指的是不能修改单个元素(如 tuple[0] = xxx),但可以用 var 声明的变量整体替换整个元组。


2.6.3 访问元组元素

通过 元组名[下标] 访问,下标从 0 开始:

Cangjie
main() {
    var pi = (3.14, "PI")
    println(pi[0])    // 3.140000(第一个元素)
    println(pi[1])    // PI(第二个元素)
}

运行结果:

Bash
3.140000
PI
⚠️WARNING

下标只能是编译期确定的整数常量,不能是变量。且下标不能越界。


2.6.4 带类型参数名的元组

可以给元组的每个位置起个名字,让代码更易读:

Cangjie
func getFruitPrice(): (name: String, price: Int64) {
    return ("banana", 10)
}

main() {
    let tmp = getFruitPrice()
    var a = tmp[0]       // "banana"
    var b = tmp[1]       // 10
    b++
    println("b = ${b}, tmp[1] = ${tmp[1]}")
}

运行结果:

Bash
b = 11, tmp[1] = 10
ℹ️NOTE
  • 参数名只是标注用途,不能当作变量名来访问元素(如 tmp.name 是不合法的)
  • 要么全部位置都起名字,要么全部不起,不能混用
Cangjie
let a: (name: String, Int64) = ("banana", 5)      // ❌ 报错:不能混用有名和无名
let b: (name: String, price: Int64) = ("banana", 5) // ✅ 全部有名
b.name                                              // ❌ 报错:参数名不能当变量用

元组使用小技巧

元组可以用来快速交换变量批量赋值,非常方便:

Cangjie
main() {
    var a = 1
    var b = 2

    // 交换 a 和 b 的值,不需要临时变量
    (a, b) = (b, a)     // 现在 a = 2, b = 1

    // 批量赋值
    (a, b) = (4, 5)     // 现在 a = 4, b = 5
}
💡TIP

交换变量的值时,用元组一行搞定,比传统写法(需要临时变量)简洁得多!

2.6.5 小结

概念 要点
定义 (T1, T2, ..., TN),至少二元
特点 长度固定、元素不可单独修改、类型可不同
访问元素 元组名[下标],下标从 0 开始
类型参数名 可以给位置起名,但只能用下标访问,不能通过名字访问

2.6.6 常见问题

Q1:为什么元组至少要有两个元素?

因为只有一个元素的元组没有意义——如果只有一个值,直接用那个值的类型就好了,不需要再用元组包一层。而且只有一个元素的 (x) 在语法上会被编译器理解为"括号表达式",而不是元组。

Q2:元组可以嵌套吗?

可以!元组里面可以再放元组:

Cangjie
let nested = (1, ("a", "b"), true)
println(nested[1][0])    // 输出:a

这在需要组织复杂数据结构时很有用。