137 lines
8.0 KiB
Markdown
137 lines
8.0 KiB
Markdown
# 14 · 反射与表示
|
|
|
|
0/16 项已确认。当前推进 14-01;本分类尚未完成选择。
|
|
|
|
本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。
|
|
|
|
## 14-01 运行时反射的基本承诺
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定普通程序默认可以观察哪些信息,哪些需要显式声明,以及元数据是否可以被裁剪。
|
|
|
|
## 14-02 类型查询与类型描述的身份
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定能查询什么、返回什么,如何比较查询结果;明确静态类型、运行时实际类型与抽象接口之间的关系。依赖【类型系统】【对象与类型模型】。
|
|
|
|
## 14-03 元数据的内容与可用性
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定字段名、参数、注解、文档、源码位置等分别是否可查询,以及信息缺失、不同构建配置下的行为。
|
|
|
|
## 14-04 动态读取成员
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定按名称查找的对象范围、查找规则,以及成员不存在、不可访问、读取触发计算时的行为。依赖【对象与类型模型】【定制协议】。
|
|
|
|
## 14-05 动态修改成员
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定是否允许新增、写入、删除成员,以及只读值、类型不匹配和修改失败的行为。依赖【类型系统】【对象与类型模型】。
|
|
|
|
## 14-06 动态调用
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定是否支持通过反射调用函数或成员,以及参数匹配、默认参数和调用失败的规则。依赖【函数与调用】。
|
|
|
|
## 14-07 反射权限与封装
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定查看描述、读取、修改、调用分别需要什么权限,以及跨模块和私有成员的边界。依赖【模块与封装】【安全模型,如有】。
|
|
|
|
## 14-08 调试表示
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定默认调试文本、定制方式、信息隐藏要求,以及是否要求稳定、唯一或可重新解析。
|
|
|
|
## 14-09 用户字符串与格式化
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定用户文本与调试表示的关系、默认回退、格式参数和转换失败行为。依赖【定制协议】【格式化语法】。
|
|
|
|
## 14-10 表示过程的执行边界
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定生成文本能否执行用户代码、产生副作用或抛错,以及循环、递归深度、长度和并发修改的处理。
|
|
|
|
## 14-11 可序列化的值与定制入口
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定哪些值可以保存,如何处理函数、类型描述、外部资源及不支持的值;明确是否依赖反射。依赖【值与资源模型】【定制协议】。
|
|
|
|
## 14-12 数据格式、模式与版本兼容
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定语言承诺与格式库的分工,以及名称、缺失字段、未知字段和版本变化的处理。
|
|
|
|
## 14-13 反序列化与有效状态恢复
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定如何选择目标类型、是否调用构造或校验逻辑,以及无效数据、部分恢复失败的行为。依赖【类型系统】【构造与不变量】【资源管理】。
|
|
|
|
## 14-14 身份、共享引用与循环的保存
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定保存树还是对象图、何时保留共享关系,以及循环、不支持的引用和恢复后身份的语义。依赖【身份与相等性】【内存与引用模型】。
|
|
|
|
## 14-15 反序列化的权限与资源限制
|
|
|
|
- [ ] 待讨论
|
|
|
|
确定输入能否指定类型或执行定制代码,以及不可信数据、超限输入和错误报告的默认规则。依赖【错误处理】【安全模型,如有】。
|
|
|
|
## 14-16 跨分类一致性验收
|
|
|
|
- [ ] 待讨论
|
|
|
|
用一组完整例子核对反射、权限、表示、恢复与相关分类的规则;记录并解决冲突及阻塞。
|
|
|
|
## 当前问题的方案与语言对照
|
|
|
|
以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。
|
|
|
|
当前仍在讨论 **14-01:普通程序拿到一个陌生值,默认能查询多少结构信息?** 例如,检查工具能否直接知道 `Account` 有 `name` 和 `token` 两个字段?
|
|
|
|
下面是相关语言的对照。取舍和启发是我们的分析,不代表这些语言的历史设计动机。
|
|
|
|
| 语言 | 规则与具体行为 | 好处、代价及对我们的启发 |
|
|
|---|---|---|
|
|
| **Python** | 许多普通实例可用 `vars(x)` 取得属性字典;没有 `__dict__` 的值会报 `TypeError`。`dir(x)` 可以被定制,也不保证列出完整、准确的属性集合。[官方文档](https://docs.python.org/3/library/functions.html#vars) · [dir](https://docs.python.org/3/library/functions.html#dir) | 通用检查很方便,但“列出名称”“实例存储”“所有可访问属性”并不相同。启发:不能只设计一个含糊的“查看所有字段”操作。 |
|
|
| **JS** | `Reflect.ownKeys({name: "林"})` 返回 `["name"]`,枚举自身属性键,包括不可枚举属性和 Symbol。`#token` 私有元素不属于普通属性,不会这样列出。[ECMAScript 规范](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.ownkeys) · [私有元素](https://tc39.es/ecma262/2024/#sec-privateelement-specification-type) | 对普通属性默认可检查,适合动态工具;代价是这些名称成为可观察行为。启发:可以对普通数据开放反射,同时为私有状态设置独立边界。 |
|
|
| **TS** | 类型注解、接口等静态信息通常被擦除。例如 `interface Account { name: string }` 不会自动产生可供运行时查询的接口描述;运行时仍使用 JS 的机制。[官方文档](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 静态检查不必带来完整运行时元数据成本;代价是运行时校验、按接口生成表单等功能需要额外描述。启发:查询对象现有属性与查询静态类型定义必须分开。 |
|
|
| **Go** | 标准库 `reflect` 能查询结构体字段,包括未导出字段的描述。但取得描述不等于取得全部操作权限:对来自未导出字段的值调用 `Interface()` 会 panic,修改还受 `CanSet()` 等条件限制。[官方文档](https://pkg.go.dev/reflect) | 通用工具能使用结构元数据,但必须处理权限和操作前提。启发:**知道字段存在、读取字段值、修改字段是不同能力**。 |
|
|
| **Rust** | 稳定版标准库的 `Any` 支持类型识别及向具体类型转换,例如 `x.is::<Account>()`;它不提供通用字段枚举。`#[derive(Debug)]` 可以生成调试输出代码,这本身不等于开放字段反射。实验性的编译期反射另当别论。[Any 文档](https://doc.rust-lang.org/std/any/index.html) · [derive 文档](https://doc.rust-lang.org/book/appendix-03-derivable-traits.html) | 可以按需提供能力,避免要求所有值都携带通用字段描述;代价是通用工具需要显式适配或生成代码。启发:**调试打印可以独立于运行时结构反射存在**。 |
|
|
|
|
这些实践不能直接一一对应我们的选项。一门语言可以同时采用不同规则,例如:普通属性默认可枚举,静态接口被擦除,调试表示又通过显式生成提供。
|
|
|
|
回到 **14-01**,我们的三个方向仍是:
|
|
|
|
- **A.不保证通用结构反射**:陌生值只能通过主动提供的接口接受检查。语言承诺较少,通用工具需要更多适配。
|
|
- **B.显式参与结构反射**:只有声明参与或提供描述的值,才能通过统一机制检查。暴露范围可控,但需要维护描述。
|
|
- **C.默认提供结构反射**:对适用的结构化值,默认保证可以查询结构;访问权限另外规定。通用工具方便,但元数据需要成为语言承诺的一部分。
|
|
|
|
我仍建议先考虑 **B**:它让我们能够分别决定反射、调试和序列化的能力。不过语言用途尚未确定,这只是建议,尚未采用。
|
|
|
|
如果选 B,我建议同时确定两个验收边界:**“没有反射描述”必须区别于“有描述但没有字段”;已经承诺可查询的描述,发布构建不能静默裁剪。** 权限规则留给 14-07。
|
|
|
|
你倾向 **A、B、C** 中哪一个?如果选 B,是否一并接受上面两个边界?
|
|
|
|
## 讨论来源
|
|
|
|
《语言设计 14:反射与表示》,整理日期 2026-10-28。章节编号沿用原清单。
|
|
|