LSR 012 - 元组类型规范¶
基本信息¶
LSR 编号 012
标题 元组类型规范
作者 Ziyang-Bai
状态 草案
类型 标准规范
创建日期 08-09-2026
归属项目 编译器、标准库
摘要¶
定义 Lamina 元组类型。元组是固定长度、按位置索引、创建后不可变的匿名积类型,可用于函数返回、临时组合和模式匹配 [1]。本规范同时规定元组与分组、函数实参、数组及区间构造之间的语法边界。
技术规范¶
1. 范围¶
元组用于组合少量按位置区分的值。元组的长度和各位置元素类型共同组成其类型。元组字面量包含至少两个元素;分组、函数调用、数组和区间分别使用各自的语法规则。
2. 元组类型¶
元组类型由一组有序元素类型组成。
(int, text)
(int, text, Expr)
元组长度固定
元组元素可以是不同类型
元组类型由长度和每个位置的类型共同决定
元组值默认不可变
元组类型是结构类型;元素类型序列相同的两个元组类型相同
3. 元组字面量¶
元组字面量使用圆括号,并以逗号分隔元素。
let pair = (1, "one")
let triple = (1, "x", true)
非空元组按元素表达式推导类型
元组字面量至少包含两个元素
单元素圆括号表达式按分组表达式解析
(a, b)始终解析为二元素元组函数名后紧跟的
f(a, b)按函数调用解析std.interval_open(a, b)是普通函数调用,其结果为开区间 [4]
let a = (1) # 分组表达式,类型为 int
4. 元数¶
元组字面量的元数至少为二。(value) 是分组表达式;f() 是零实参函数调用。函数的返回语义由核心语言规范定义 [1]。
5. 元组访问¶
元组元素按位置访问,索引从 1 开始,与 Lamina 现有线性代数索引规则保持一致。
let p = (10, "x")
let a = p.1
let b = p.2
元组索引必须是编译期常量正整数
第一个元素的位置为
1访问位置超过元组长度是编译错误
元组位置访问读取创建元组时绑定在该位置的元素
6. 元组解构¶
元组可在 let 和 match 中解构。
let (x, y) = (1, 2)
match value {
(a, b) => a + b
}
解构模式长度必须与元组长度一致
_可忽略对应位置解构绑定的变量类型由对应位置推导
解构保持原元组值,并为各位置创建对应绑定
7. 函数返回元组¶
函数可以返回元组作为单一返回值。
func divmod(a int, b int) -> (int, int) {
return (a / b, a % b)
}
let (q, r) = divmod(10, 3)
8. 相等性与哈希¶
元组按位置结构比较。
两个元组长度不同,则类型不同
两个同类型元组逐位置相等时,整体相等
只有所有元素可比较时,元组才支持
==只有所有元素可哈希时,元组才可作为哈希键
9. 求值与存储语义¶
元组字面量的元素表达式按源码从左到右各求值一次。元组值创建后,元素位置和元素绑定保持不变。
元组的不可变性是浅层不可变;元素若引用可变对象,该对象仍遵循自身语义
实现可以内联、装箱或共享元组存储;各种表示具有相同的求值顺序、结构相等和可观察生命周期行为
跨模块接口必须保留元组长度、元素顺序和每个位置的静态类型
10. 与数组、集合和区间的区别¶
类型 |
长度 |
元素类型 |
顺序 |
主要用途 |
|---|---|---|---|---|
元组 |
固定 |
可异构 |
有序 |
多值组合 |
数组 |
可变或运行期长度 |
通常同构 |
有序 |
程序式序列 |
集合 [3] |
运行期大小 |
同构 |
无序 |
去重数学集合 |
区间 [4] |
两个端点 |
同构 |
有序边界 |
表示连续或离散范围 |
11. 诊断¶
实现至少应区分下列错误:
TupleArityMismatch:解构模式长度与元组长度不同TupleIndexNotConstant:位置访问不是编译期常量TupleIndexOutOfBounds:位置不在1到元组长度之间TupleAssignment:试图修改元组元素绑定TupleTypeMismatch:目标元组类型与元素类型序列不兼容
错误名称可以映射到实现的统一诊断系统。
12. 兼容性¶
(a, b) 统一表示元组。原开区间写法 (a, b) 迁移为 std.interval_open(a, b) [4]。