RFC-0042:不可为 null 类型

RFC-0042:不可为 null 的类型
状态已拒绝
区域
  • FIDL
说明

FIDL 库作者可以使用 ? 将某些类型和成员标记为可为 null。这提出了一种将类型和成员标记为不可为 null 的方法。

作者
提交日期(年-月-日)2019-04-01
审核日期(年-月-日)2019-04-01

拒绝理由

Poisson d'avril

不过,在布局支持可为 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;
}

另一个示例是放置在线外的“盒装”类型:

// 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 引用描述为“数十亿美元的错误”,并指出它可能会导致安全漏洞。

测试

由于编译器更改不会影响 IR 或绑定,因此我们需要为 fidl 前端编译器添加测试。

缺点、替代方案和未知情况

有人提出了关于在 FIDL 语法中将 ISO 8859-1 替换为 US-ASCII 字符的一些疑虑,但此字符可以胜任此任务

在先技术和参考文档

如上所述,Kotlin、C#、Swift 和 TypeScript 都允许将类型声明为不可为 null。