元组(Tuple)
元组是定长、异构、不可变的值序列。字面量与类型同形:(3, "甲") 的类型就是 (int, string),分量个数与每个分量的类型都是类型的一部分,(int, string) 与 (int, int)、(int, string, int) 互为不同类型。
字面量与类型
func main() -> int
{
val t = (3, "甲");
print(t, t is int);
val u: (int, string, float) = (1, "乙", 2.5);
print(u.Item0, u.Item1, u.Item2);
val nest = ((1, 2), "x");
print(nest.Item0.Item1, nest);
val p = (1);
print(p, p is int);
return 0;
}(3, 甲) False
1 乙 2.5
2 ((1, 2), x)
1 True- 至少两个分量才成元组:
(1)是带括号的表达式,类型还是int。 - 嵌套合法,外层分量自身还是元组,逐层
.Item下钻。 - 打印形如
(3, 甲),字符串分量不带引号。
位置成员:Item0 起
分量用 0 基的位置成员访问,t.Item0 是第一个分量。分量只读,元组是不可变值。
分量个数写在类型里,越界与异名成员都在编译期报错,不会等到运行期:
func main() -> int
{
val t = (3, "甲");
print(t.Item0, t.Item1);
return 0;
}3 甲error MS3281: Tuple '(int32, string)' has no component 'Item2': components are read-only .Item0 .. .Item1 (0-based).下标读 t[0] 与 .Item0 等价,仅收界内常量整数,动态表达式、越界与多参下标会直接报错:
func main() -> int
{
val w: (int, string) = (3, "c");
print(w[0], w[1]);
return 0;
}3 c解构与多返回值
val / var 的声明位支持元组解构,一次命名多个分量。var 解构出的分量可以再赋值。
func DivMod(a: int, b: int) -> (int, int)
{
return (a / b, a % b);
}
func Sum(p: (int, int)) -> int
{
return p.Item0 + p.Item1;
}
func main() -> int
{
val (q, r) = DivMod(17, 5);
print(q, r);
print(Sum((3, 4)));
var (a, b) = (1, 2);
a = 9;
print(a, b);
return 0;
}3 2
7
9 2函数返回元组是多返回值的常规形态,调用点可以直接解构接住。元组也能整体当参数传,元素静态类型为元组的列表,for-in 迭代变量位可以直接解构:
func main() -> int
{
val xs: list<(int, string)> = [(1, "甲"), (2, "乙")];
for (n, s) in xs
{
print(n, s);
}
return 0;
}1 甲
2 乙list.Zip 与 map.Entries() 同样产出元组列表,解构、注解赋值与 .Item 成员都可用(见映射)。
判等:引用同一性
== / != 比实例身份,与 class、容器同律:各自构造的两个元组即使内容完全相同也不等,同一实例的别名才相等。要比内容,解构后逐分量比:
func main() -> int
{
val p = (1, "甲");
val q = (1, "甲");
val alias = p;
print(p == q, p == alias);
print(p.Item0 == q.Item0 && p.Item1 == q.Item1);
return 0;
}False True
True可空元组照常参与:可空对可空、可空与非空混对都放行,解包后比身份,== null 判空照旧。
与容器的分工
定长且编译期已知结构的数据可以选元组,动态长度与同构元素选 List,异构集合退化为 list<any> 加运行期收窄,元组的优势是可以把结构提前到编译期。分量类型参与函数签名与泛型实参(list<(int, string)>),没有增删变异面。
注意
(1,)与()都过不了解析:元组至少两个分量,两个以上分量的尾逗号(1, 2,)仍合法;空括号不是表达式。- 可空元组本身照常判空收窄:
if (pay != null)分支内可直接解构或pay[0]取分量,但对元组内的可空分量仍不收窄,需要先解构取出分量再判。 - match 与
is里的元组模式见模式,any 通道里的元组值可按类型形判形,if e is (int, string) p命中时p绑定元组值,形状不符静默为 False。无类型的解构形is (k, v)不支持。
最后更新于 2026年10月9日
