9.3 KiB
03 · 值与类型
13/30 项已确认。当前推进 03-14;null 是否为对象仍未确认。其余分类中的类型、赋值和条件规则须与本章已有决定核对。
本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。
03-01 动态类型
- 已确认
操作根据运行时对象的类型检查;不要求执行前通过静态类型检查。不适用的类型组合在运行时失败。
03-02 名字与对象绑定
- 已确认
变量名绑定对象,类型属于对象;b = a 共享对象,重新绑定 a 不改变 b。
03-03 隐式转换政策
- 已确认
需要转换类型时必须显式写出;不靠自动转换接受不匹配的操作数,例如 "41" + 1 报 TypeError。
03-04 数值类型与支持范围
- 已确认
对外统一为 Number,覆盖整数与有理数,大小自动调整;不引入无穷大、NaN、虚数,正负零视为同一个数。精确性及异常运算另见下项。
03-05 整数性质与循环次数
- 已确认
记录数值是否为整数;按次数循环要求正整数,零、负数和非整数不满足要求。具体错误形式交由 03-29 统一。
03-06 字符串算术操作
- 已确认
确定字符串拼接、减法与重复运算的支持范围。
**已确认规则:**两个 String 可以用 + 拼接,不支持字符串减法;后续已修订为支持 String * 整数值 Number,完全等价于 duplicate,包含相同的参数检查与失败行为。
03-07 数值精确性
- 已确认
确定有理数存储和四则运算是否始终精确,是否允许舍入。
已确认规则:1 / 3 精确保存为 1/3;1/3 + 1/3 得到 2/3;1/3 * 3 得到整数 1。如何显示另由 03-09 决定。
03-08 数值异常
- 已确认
确定除零等不成立的数值运算如何失败,哪些情况交给平台模块。
已确认规则:1 / 0、0 / 0、1 / (1 - 1) 都抛出算术错误,停止本次表达式求值。具体错误名称、捕获和传播机制由【错误与异常】及 03-29 对齐。
03-09 数值输入与显示
- 已确认
确定小数文字表示什么数、循环小数如何显示,以及显示后能否无损读回。依赖【词法与语法】。
**已确认规则:**数值按精确值解释,默认输出最简分数,分母为正;整数直接显示为整数,零显示为 0。
03-10 基本类型清单
- 已确认
确定本轮内置哪些类型,以及明确不提供哪些类型。
**已确认规则:**本轮提供 Number、String、Boolean、空值类、List、Map、Tuple、Set、Bytes、函数类、类型对象所属的类。具体类名暂定。 空值类的对象地位在 03-14 被重新提出,仍待确认;不能据此宣布 null 已确定为对象。
03-11 字符串的值模型
- 已确认
确定字符单位、Unicode 处理及索引单位;补齐空字符串等边界。
**已确认规则:**合法 Unicode 标量序列;保留原码点、不自动规范化;默认按码点计数,字素簇使用专门接口;索引从零开始、支持负索引、单个索引越界报错;普通正向切片左闭右开、越界截断、空范围返回空字符串。 创建或解码时拒绝非法编码和孤立代理项,不自动替换或丢弃;原始数据用 Bytes 保存。
03-12 字符串重复方法
- 已确认
确定名称、次数参数、零和负数、错误行为及返回值。
已确认规则:s.duplicate(n) 返回重复后的 String,不修改接收者。n 必须是非负整数值的 Number;零次返回空字符串,负数、非整数及其他类型报错,不做隐式转换。
03-13 布尔值与条件转换
- 已确认
确定布尔值是否独立于数字,以及条件位置接受布尔值还是其他值。依赖【控制流】。
已确认规则:Boolean 独立于 Number;条件表达式只接受 Boolean 对象。true、false 可以作为条件,数字、字符串、容器、空值等直接作为条件均报 TypeError。具体控制流语法由【控制流】对齐。
03-14 空值与缺失
- 待讨论
确定是否区分空值、缺失、未初始化和无返回值,以及误用时的行为。
03-15 复合值规则
- 待讨论
为选中的容器、元组、记录或枚举等确定成员类型限制、缺失成员及递归结构规则。
03-16 用户定义类型的能力
- 待讨论
确定用户能定义哪些类型,哪些能力仅供内置类型使用。依赖【对象与类型模型】。
03-17 类型身份与兼容性
- 待讨论
确定按名字还是结构认类型、如何处理子类型,以及哪些类型可以互相替代。
03-18 运行时类型查询
- 待讨论
确定如何取得类型、检查类型及检查能力;明确精确类型与子类型检查的区别。
03-19 显式转换接口
- 待讨论
确定转换入口、支持的转换、可能丢失信息的转换及失败行为。
03-20 泛型与容器类型约束
- 待讨论
决定是否支持参数化类型或带成员约束的容器;支持则规定运行时如何检查。
03-21 可选类型标注
- 待讨论
决定是否提供;提供则明确其用途及是否影响运行行为。
03-22 顶级类型与顶级类
- 待讨论
分别决定是否存在能容纳所有值的类型,以及是否存在统一祖先类。
03-23 可变性与共享
- 待讨论
确定哪些对象可变,以及多个名字共享对象时能观察到什么变化。
03-24 复制语义
- 待讨论
确定赋值之外是否提供复制、浅复制和深复制,以及循环引用如何处理。
03-25 相等与身份
- 待讨论
确定内容相等和同一对象如何区分,以及不同类型之间如何比较。
03-26 哈希与键的限制
- 待讨论
确定哪些值可作集合成员或映射键,保证相等、哈希和可变性规则一致。
03-27 参数与返回值的绑定
- 待讨论
确定传参、返回、重新绑定及修改对象的可见效果。依赖【函数与调用】。
03-28 显式引用能力
- 待讨论
决定能否直接取得并传递“变量存储单元”的引用;不支持也可完成此项。
03-29 类型相关错误契约
- 待讨论
统一类型不匹配、值不合法、转换失败等情况的错误分类。依赖【错误与异常】。
03-30 跨分类一致性验收
- 待讨论
用一组正常和失败示例核对类型、转换、对象、运算、函数与控制流规则,消除冲突和阻塞。
当前问题的方案与语言对照
以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。
可以,你要的空状态表示“变量位置存在,但当前没有指向对象”。
不过,“避免回收”这里需要区分两件事:
result = null
……之后……
result = calculate()
这是先保留名字,之后再绑定对象。前面还没有计算结果对象,因此没有对象需要保活。名字什么时候有效,由作用域规则决定。
如果已经有对象,情况不同:
a = 某个对象
b = a
a = null
在采用强引用与自动回收的模型中,b 仍持有该对象,就不能提前回收它;如果所有有效强引用都消失,对象才可能被回收。**把变量设成 null 会解除它原来的引用,不会保护原对象。**具体回收机制属于【运行时与内存管理】,尚未确定。
各语言也区分“空状态”和“对象保活”:
| 语言 | 空状态怎样表达 | 对我们的启发 |
|---|---|---|
| Python | None 本身是一个对象,名字绑定到它。对象模型 |
可以保持所有可绑定值都是对象的统一规则。 |
| JS / TS | null 是独立的原始值,不是对象;TS 另有静态类型约束。JS 规范、TS 文档 |
可以在语言层面明确允许“无对象”的值。 |
| Go | 指针变量可以为 nil,表示没有指向对象,变量本身仍存在。语言规范 |
接近你描述的“位置存在、目标为空”。 |
| Rust | Option<T> 的 None 表示其中没有 T 值,不要求使用空指针实现。官方说明 |
“没有目标对象”的语义不必绑定某种内存布局。 |
这里还有一个需要明确的设计边界:
- 空引用例外:名字可以绑定对象,也可以持有
null;null不属于对象。 - 统一对象模型:
null是空值类的对象,用它表示“没有业务对象”。
你说的“没有对象”,更接近 1。这会成为之前“所有值都是类的实例”的一个明确例外;方案 2 则保留那条统一规则。两者都能实现先声明、后赋值。
你希望 null 本身也不是对象,采用方案 1,对吗?
讨论来源
《语言设计 03:值与类型》,整理日期 2026-10-28。章节编号沿用原清单。