AI Library · 知识库

# 静态与动态:把反馈提前到哪一层

学习目标:区分静态调用约束、外部输入校验与运行时行为,判断类型声明实际减少哪类维护风险。前置阅读:端口解析与报告输出,理解参数、异常和写入协议即可。本篇只分析已有程序,不把语言分成“有保证”和“无保证”两类。

# 案例与变化

原 parsePort 接收已经是字符串的配置,现在配置入口从文本文件改为任意 JSON 值:调用方可能交来 "8080"、8080、null 或数组。产品要求仍只接受字符串,不自动把数字或对象转成文本。

这不是把原解析器改成“任何值都能转端口”。新契约应分层:入口先确认值是字符串;旧解析器继续保证 1~5 个 ASCII 数字和 1~65535 范围;失败时启动流程停止。成功值、前导零处理和已有拒绝集合保持不变。

# 实现需要改变什么

TypeScript 原例只替换 JS 函数签名为 parsePort(text: string): number,函数体和调用驱动完全共享。若新入口值以 unknown 表达,调用方须在调用前检查并收窄为 string;对外部值写 as string 只是告诉检查器相信开发者,不会建立运行边界。

机制事实:TypeScript 类型标注在生成 JavaScript 时被擦除,不改变运行行为,参见类型擦除。unknown 与收窄用于限制尚未确认类型的值的操作;它们不代替业务检查。

JS 在同一个入口执行 typeof 检查后调用原函数。Python 需要相应的运行时字符串检查;原 text: str 注解不会自动拒绝整数。参见 Python typing 的运行时边界。因此 JS/TS 的运行修改基本一致,区别主要在“内部代码把未检查的值直接传入时,工具能否提前指出”。

Rust、Go、Java、Kotlin、C++ 的原函数参数也只描述已解码的文本。接入 JSON 时,解码入口仍必须确认字段形状;编译器保证传参类型相容,不替解析库决定缺字段、空值或数字字段如何处理。本篇不选择 JSON 库、不新增依赖,也不声称这些入口已经实现。

另一个独立变化是给 Python 报告函数的 out 增加结构化协议注解。当前函数直接执行 out.write(...);加 typing.Protocol并配置静态检查后,可提前检查已知调用点是否提供合适签名,但报告正文、临时文件创建和关闭代码不因此改变。

# 保证与责任

层次 在本次变化中能保证什么 不能据此推导什么
静态签名 已检查代码中的传参形状 外部 JSON 一定是字符串
入口类型检查 当前值确为文本 文本符合端口协议
解析与范围检查 成功值满足端口规则 对应服务可连接
报告能力检查 目标具有要求的方法或类型关系 写入完整、及时关闭、持久化成功

工具反馈:Rust 的 Write 泛型约束、Go 的 io.Writer 方法集、Java 的 Writer 类型关系能在编译期发现不相容目标。Python 当前未注解的 out 则通常在执行有关调用时暴露错误。Python 加协议检查后的反馈取决于工具是否运行、调用点是否受检查,不能把语言注解本身当作运行时强制机制。

运行契约:即使 Python 对象有 write 方法,也可能接收 bytes 而不是 str。即使 Java 的目标属于 Writer,它也可能在写入时抛 IOException。参见 Python 文本与二进制流和 Java Writer。类型一致不是设备健康检查。

调用方责任:新 JSON 入口必须拒绝非字符串,而不是捕获任意异常后假定都是坏端口;原 JS 驱动保留对未知异常的重新抛出。报告调用方必须管理资源和处理失败;协议声明没有把这些职责转给类型检查器。详细责任分层见失败暴露不等于处理正确。

# 取舍与适用条件

设计分析:跨模块调用多、函数签名经常变化时,静态反馈能把部分问题提前到修改提交前,尤其有助于定位还未迁移的调用点。代价是维护声明、编译或检查配置,以及边界上的收窄代码。一个只调用一次的短脚本不必为了“更静态”复制标准库整套协议,但外部输入检查仍不可省略。

动态调用减少了某些显式适配声明,适合协议已经稳定、调用路径很小的脚本;它没有免除验证,只是要求测试或真实执行覆盖更多错误路径。反过来,静态工程也需要测试,否则 <= 5 被改成 < 5 这样的业务错误仍可能通过所有类型检查,见库存边界。

不能把语言标签当成工具配置:TS 的 strict、Python 的检查器覆盖范围、第三方类型声明质量都会改变反馈效果。也不能以 JS 和 TS 共享运行时代码为由断言团队维护成本相同;本篇没有测量编辑器体验、构建耗时或缺陷率。

# 验证与相关阅读

没有新增代码或执行记录。JSON 入口和 Python 协议注解是明确的设计变化,未伪装成现有实作;非字符串输入不在原端口测试契约内。版本基线见主题首页,真实执行与未覆盖情况统一见验证记录。

相关阅读:端口解析 · 报告输出 · 保证由谁承担。