| RFC-0042:不可为 null 的类型 | |
|---|---|
| 状态 | 已拒绝 |
| 区域 |
|
| 说明 | FIDL 库作者可以使用 ? 将某些类型和成员标记为可为 null。此提案提出了一种将类型和成员标记为不可为 null 的方法。 |
| 作者 | |
| 提交日期(年-月-日) | 2019-04-01 |
| 审核日期(年-月-日) | 2019-04-01 |
拒绝理由
不过,在布局支持可为 null 的上下文(例如,表字段、可为 null 的类型别名)中强制执行存在性的基本理念可能会纳入另一项 FTP 中。
摘要
FIDL 库作者可以使用 ? 将某些类型和成员标记为可为 null。此提案提出了一种将类型和成员标记为不可为 null 的方法。
设计初衷
借助类型别名,库作者可以在声明中将可为 null 性纳入类型中,例如:
using MiddleName = string:255?;
明确将可为 null 的类型标记为不可为 null 可能很有用,例如:
struct FullName {
GivenName given_name;
vector<MiddleName> middle_names; // names shouldn't be null
FamilyName family_name;
}
另一个示例是放置在行外的“boxed”类型:
// An "out-of-line" full name
struct InappropriateFullName {
option<FullName> full_name; // full_name shouldn't be null
};
设计
此提案为类型引入了不可为 null 的指定符,用于将可为 null 的类型标记为不可为 null。这是对源语言的更改,但不会更改有线格式、IR 或绑定。
在上述情况下,我们会使用:
struct FullName {
GivenName given_name;
vector<MiddleName¿> middle_names;
FamilyName family_name;
}
且:
struct InappropriateFullName {
option<FullName¿> full_name;
};
为了与类型可为 null 性的语法保持对称,我们使用了倒问号符号。
这是 Unicode 码位 \u00BF,可在任何键盘上轻松输入。
其他可能的用例是添加不可为 null 的 table 成员:
table FullName {
GivenName¿ given_name;
MiddleName middle-name;
FamilyName¿ family_name;
};
或者指定某个 xunion 成员必须始终存在:
xunion PreferredOperatingSystemVersion {
float32 Windows;
float32 MacOS;
float32 Linux;
float32¿ Fuchsia;
};
实施策略
这并非重大变更,但随着 FIDL 中对广义类型别名的新支持,对它的需求最近有所增加。
工效学设计
不可为 null 类型是 Kotlin、C#、Swift 和 TypeScript 等语言的一项热门功能。这是 Dart 的一项热门功能请求。
文档和示例
语法和语言文档将需要更新。
向后兼容性
此功能向后兼容。
性能
某些不可为 null 的类型(例如结构体)比其可为 null 的变体具有更紧凑的表示形式,因此可以实现更高效的传输。
安全
Tony Hoare 将 null 引用描述为“价值十亿美元的错误”,并且 null 引用可能会导致安全漏洞。
测试
作为对 IR 或绑定没有影响的编译器更改,我们需要为 FIDL 前端编译器添加测试。
缺点、替代方案和未知因素
有人担心 ISO 8859-1 会取代 FIDL 语法中的 US-ASCII 字符,但此字符可以完成任务。
在先技术和参考资料
如上所述,Kotlin、C#、Swift 和 TypeScript 都允许将类型声明为不可为 null。