本部分包含 Fuchsia 接口定义语言文件。
另请参阅 FIDL API 评分准则。
姓名
猫咪的名字是件难事,
它不仅仅是您的节日游戏之一;
--- 一般Eliot
FIDL 中定义的名称用于生成每种目标语言的标识符。 有些语言会给各种名称包含语义或常规含义, 表单。例如,在 Go 中,标识符中的首字母是否是 大写用于控制标识符的可见性。因此,许多 语言后端会转换库中的名称, 展示内容。本部分的命名规则采用 在 FIDL 源代码的可读性与每个目标平台的可用性之间取得平衡 确保各目标语言的一致性
请避免使用常用的保留字,例如 goto
。语言后端
将保留字转换为非保留标识符,但这些将
降低这些语言的易用性。避免使用常见的保留字可以
应用这些转换的频率。
虽然某些 FIDL 关键字在目标语言中通常也是保留字,
(例如 C 和 C++ 中的 struct
),因此应避免使用,其他 FIDL
关键字(尤其是request
和handle
)通常都是描述性的
您可以酌情使用。
名称的开头或结尾不得包含下划线。开头或结尾 下划线在某些语言中具有语义含义(例如,前导下划线 控件可见性)和其他语言中的常规含义(例如, 结尾的下划线通常用于 C++ 中的成员变量)。 此外,FIDL 编译器会使用前导和尾随下划线来移除 标识符,以避免冲突。
使用 size
一词命名字节数。使用 count
一词来命名
其他一些数量(例如,矢量中项的数量)
结构体)。
支持请求定义
有时,有多种方法可以决定 标识符。我们的样式如下:
- 请以美式英语的原始短语(例如,“Non-Null HTTP Client”)
- 请移除标点符号。(“非 Null HTTP 客户端”)
- 全部小写(“non null http 客户端”)
- 根据适用于指定样式的样式,执行以下某项操作
标识符:
<ph type="x-smartling-placeholder">
- </ph>
- 将空格替换为下划线(“_”)以表示小写蛇形
(
non_null_http_client
)。 - 将空格大写并替换为下划线(蛇形大写)
(
NON_NULL_HTTP_CLIENT
)。 - 将每个单词的首字母大写,然后将所有单词连接起来
大驼峰式命名法 (
NonNullHttpClient
)。
- 将空格替换为下划线(“_”)以表示小写蛇形
(
用法
下表列出了用例的用法与元素的对应关系:
元素 | 大小写 | 示例 |
---|---|---|
bits |
大驼峰式命名法 | InfoFeatures |
Bitfield 成员 | 上蛇壳 | WLAN_SNOOP |
const |
上蛇壳 | MAX_NAMES |
alias |
大驼峰式命名法 | DeviceId |
protocol |
大驼峰式命名法 | AudioRenderer |
协议方法参数 | 下蛇框 | enable_powersave |
协议方法 | 大驼峰式命名法 | GetBatteryStatus |
struct |
大驼峰式命名法 | KeyboardEvent |
结构体成员 | 下蛇框 | child_pid |
table |
大驼峰式命名法 | ComponentDecl |
表成员 | 下蛇框 | num_rx |
union |
大驼峰式命名法 | BufferFormat |
联盟成员 | 下蛇框 | vax_primary |
enum |
大驼峰式命名法 | PixelFormat |
枚举成员 | 上蛇壳 | RGB_888 |
库
库名称是以英文句点分隔的标识符列表。库的部分内容
除最后一个名称之外的其他名称也称为命名空间。每个组件
该名称采用小写形式,并且必须与以下正则表达式匹配:
[a-z][a-z0-9]*
。
我们之所以采用这些限制性规则,是因为不同的目标语言具有不同的 对命名空间、库或软件包的限定方式进行限制。我们有 选择保守型最小公分母,以确保 FIDL 有效 使用我们当前的目标语言和未来可能的目标语言 语言。
标识符名称:首选具有意义的功能角色
首选功能名称(例如,fuchsia.media
) 而不是产品或代号
(例如,fuchsia.amber
或 fuchsia.scenic
)。产品名称是合适的
当产品在 Fuchsia 之外有一些外部存在,以及
协议。例如,fuchsia.cobalt
是
Cobalt 接口协议的名称要优于 fuchsia.metrics
,因为
其他指标实现方式(例如Firebase)不太可能实现相同的
协议。
标识符名称应与参与者扮演的特定角色相关;
请避免将访问控制编码到名称中。基于角色的名称包括
描述性的名称不会像基于访问控制的名称那样快
规定一种由外部定义的关系,该关系会随着
平台不断发展演变。例如,对于涉及 FocusChain
对象的 API,
相应的名称应为 fuchsia.ui.focus
,而不是
fuchsia.ui.privileged
;如果我们决定扩大 FocusChain
对象的范围,
那么 fuchsia.ui.focus
不是一个有问题的名称。以下
应避免使用示例字词:
constrained
limited
oem
private
privileged
protected
special
vendor
标识符名称应具有实际含义;避免使用没有意义的名称。如果
fuchsia.foo.bar
和fuchsia.foo.baz
有一些共同的概念,
不妨考虑在单独库中定义这些概念
fuchsia.foo
,而不是在 fuchsia.foo.common
中。以下示例字词
应避免:
common
service
util
base
f<letter>l
zx<word>
顶级
请避免重复库名称中的名称。例如,在
fuchsia.process
库中,用于启动进程的协议应命名为
Launcher
,而不是 ProcessLauncher
,因为名称 process
已
会显示在库名称中。对于所有目标语言,顶级名称都是
以某种方式指定库名称来限定作用域。
原初别名
基元别名不得重复封装库中的名称。全部 原语别名会替换为基础原语 因此不会导致名称冲突。
alias vaddr = uint64;
常量
常量名称不得重复封装库中的名称。在所有目标中 常量名称的范围由其所属的库限定。
描述上下限的常量应使用前缀 MIN_
和 MAX_
。
const MAX_NAMES uint64 = 32;
协议
协议通过 protocol
关键字指定。
协议必须是名词短语。
通常,协议是使用表示操作的名词命名的。对于
例如,AudioRenderer
是一个名词,表示协议与
呈现音频的过程。同样,Launcher
是一个名词,表示
都与发布什么内容相关协议也可以是被动的
尤其是当它们与实现所持有的某个状态有关时。
例如,Directory
是一个名词,表示协议适用于
与实现包含的目录交互。
可以使用面向对象的设计模式命名协议。例如:
fuchsia.fonts.Provider
使用 provider
后缀,这表示
协议提供字体(而不是表示字体本身)。同样,
fuchsia.tracing.Controller
使用 controller
后缀,这表示
协议控制跟踪系统(而不是表示跟踪记录)
本身)。
名称 Manager
可作为协议
范围很广例如,fuchsia.power.Manager
。但请注意
“经理”往往会吸引大量松散相关的
可以更好地纳入多个协议的功能。
协议不得包含名称 service.
。所有协议都会定义服务。
这个词没有意义。例如,fuchsia.tts.TtsService
就违反了
评分准则。首先,Tts
前缀对于库是多余的
名称。其次,禁止使用 Service
后缀。
明确的“open
/ajar
/closed
”修饰符
对于协议,应始终指定 open
、ajar
或 closed
而不是依赖于默认值也就是说,始终优先选择 open protocol Foo {
...
,而不是仅 protocol Foo { ...
。
方法
方法必须是动词短语。
例如,GetBatteryStatus
和 CreateSession
是动词短语,
用于指明该方法要执行的操作。
在事件发生时调用的 listener
或 observer
协议的方法
应带有 On
前缀,并描述在
。例如,ViewContainerListener
协议有一个
名为 OnChildAttached
。
事件
类似地,事件(即从服务器发送至客户端的未经请求的消息)
应带有 On
前缀,并描述过去发生的事件
状态。
例如,AudioCapturer
协议有一个名为
OnPacketCaptured
。
单一方法协议
单个方法协议的方法应该是
协议中定义了这些协议的名词短语,例如Loader.Load
、Getter.Get
、
Uploader.Upload
。对于限定名词短语,例如 JobCreator
或 ProcessStopper
,则应使用非限定动词短语,例如
JobCreator.Create
或 ProcessStopper.Stop
。
属于单一方法但打算随着时间的推移发展为多方法的协议 并不一定需要遵循此命名惯例,例如,如果有 协议的已知扩展,建议的命名并非 那么最好尽早选择其他名称在 因此最好采纳默认建议。
因为替换协议比改进协议更难, 从未打算发展,但最终发现需要改用多种方法 改进现有协议,最好添加一个方法, 并可能重命名现有方法
露骨的“strict
/flexible
”修饰符
对于方法和事件,应始终指定 strict
或 flexible
而不是依赖于默认值也就是说,始终优先使用 flexible Foo();
,
只需要 Foo()
。
结构体、联合和表
结构体、联合和表必须是名词短语。
例如,Point
是一个结构体,用于定义空间中的位置和
KeyboardEvent
是一个定义键盘相关事件的结构体。
结构体、联合和表成员
在以下情况下,最好使用单个单词的结构体、联合体和表成员名称 切合实际(单字词名称在各种目标语言中的呈现方式更加一致)。 不过,如果一个字词可能不适合您, 含糊不清或令人困惑
成员名称不得重复所属类型(或影视库)中的名称,除非
如果没有属于封闭类型名称,成员名称不明确。对于
例如,包含事件发生时间的 KeyboardEvent
类型的成员
交付项应命名为 time
,而不是 event_time
,因为其名称
event
已出现在封闭类型的名称中。在所有目标中
成员名称的范围取决于所属类型。
然而,DeviceToRoom
类型会将智能设备与房间相关联
可能需要有device_id
和room_name
成员,因为
id
和 name
不明确。这两个标记都可能表示
或者房间
枚举
枚举必须是名词短语。
例如,PixelFormat
是一个定义颜色编码方式的枚举
转换为位。
枚举成员
枚举成员名称不得重复所属类型(或库)中的名称。
例如,PixelFormat
枚举的成员应命名为 ARGB
,而不是
PIXEL_FORMAT_ARGB
,因为名称“PIXEL_FORMAT
”已出现在名称中
所属类型在所有目标语言中,枚举成员名称的作用域限定为
所属的类型。
位字段
位字段必须是名词短语。
例如,InfoFeatures
是一个位字段,用于指明哪些特征
都位于以太网接口上
Bitfield 成员
位字段成员不得重复所属类型(或库)中的名称。
例如,InfoFeatures
位字段的成员应命名为 WLAN
而不是 INFO_FEATURES_WLAN
,因为名称 INFO_FEATURES
已
。
在所有目标语言中,位字段成员名称都按其
封装类型。
类型
露骨的“strict
/flexible
”修饰符
对于接受 strict
/flexible
修饰符的类型(bits
、enum
和
union
),则应始终指定此类修饰符,而不是依赖于
默认值。也就是说,始终优先选择 flexible bits ...
,而不是仅 bits ...
。
组织机构
语法
- 使用 4 个空格缩进。
- 一律不使用标签页。
- 避免尾随空格。
- 为
bits
、enum
、protocol
、struct
、table
、 以及包含不同声明的其他声明的union
构造, 一个空白行(两个连续的换行符)。 - 文件末尾只能包含一个换行符。
评论
注释使用 ///
(三个正斜杠)。库中的评论还会
会显示在生成的代码中,以便在针对
库。将评论“流经”目标语言。
在所描述的内容上方添加注释。下列情况除外: 请使用正确的大小写和长度合理的句子, 。评论长度不得超过 80 个字符,但较长的评论除外 不可避免(例如,对于较长的网址)。
注释应使用 Markdown 编写。我们依靠 CommonMark 规范。部分 工具可能会使用其他 Markdown 标准渲染输出;如果您的工具 不使用 CommonMark,因此我们鼓励开发者编写 同时兼容 CommonMark 及其工具。对 FIDL 元素的引用 应始终采用代码字体。
记录的实体是指附加了注释的任何 FIDL 元素。第一个
注释中引用任何已记录的实体时,都应提供其完整
限定名称,格式为 [`<library>/<top level declaration>.<member>`]
(例如,[`fuchsia.io/Node.clone`]
)。在以下情况下,此表单可能会生成超链接:
工具为其提供支持对记录实体的后续引用可以
请使用简写版本,前提是该简写版本清晰明确
(例如,clone
)。不带方括号的表单不会生成超链接。
请求参数、响应参数和错误类型应记录为 以下形式的列表:
+ request `param1` <description>
+ request `param2` <description>
- response `param1` <description>
- response `param2` <description>
* error <description>
请求、响应和错误必须按该顺序显示。一组给定的 参数的声明顺序也必须遵循 参数列表。术语“请求”和“response”可能被省略 参数名称只能在请求或响应参数列表之一中找到。
描述变量、字段或类型的文档注释的第一部分应为
简要说明记录实体的预期用途的名词短语;
包含无法从名称和类型推断出来的信息。通过
说明应以句点结尾。广告内容描述不应
重申记录实体的名称或其特定类型的 FIDL
语言元素(例如,struct
或 protocol
)。
/// A representation of violins displayed on the screen.
type Widget = struct {
/// A monotonically increasing id, uniquely identifying the widget.
id uint64;
/// Location of the top left corner of the widget.
location Point;
};
下面列举了一些示例来说明不应该采取的措施:
/// BAD: Widget is a representation of violins displayed on the screen.
/// BAD: struct Widget is a representation of violins displayed on the screen.
协议方法所附文档注释的第一部分应为简短内容 该方法的行为的说明,以动词开头,包括 无法从名称和类型推断出的信息。动词应为 采用现在时时,同意第三人称单数代词;以及 使用陈述语气(这实际上就是假装 “it”并指出您是在陈述事实)。通过 短语应以句点结尾。
完整示例:
/// An abstract representation of a [`fuchsia.io/Node`] whose layout is flat.
protocol File {
compose Node;
/// Acquires a [`fuchsia.mem/Buffer`] representing this file, if
/// there is one, with the requested access rights.
///
/// ## Rights
///
/// This method requires the following rights:
///
/// * [`fuchsia.io/OPEN_RIGHT_WRITABLE`] if `flags` includes
/// [`fuchsia.io/VMO_FLAG_WRITE`].
/// * [`fuchsia.io/OPEN_RIGHT_READABLE`] if `flags` includes
/// [`fuchsia.io/VMO_FLAG_READ`] or [`fuchsia.io/VMO_FLAG_EXEC`].
///
/// + request `flags` a bit field composing any of
/// `VMO_FLAG_READ`, `VMO_FLAG_WRITE`, or `VMO_FLAG_EXEC`.
/// - response `buffer` the requested `fuchsia.mem/Buffer`, or
/// null if there was an error, or the buffer does not exist.
/// * error a zx_status value indicating success or failure.
/// * see [`fuchsia.mem/Buffer`]
/// [`fuchsia.mem/Buffer`]:
/// https://fuchsia.googlesource.com/fuchsia/+/HEAD/sdk/fidl/fuchsia.io/
GetBuffer(struct {
flags uint32;
}) -> (resource struct {
buffer box<fuchsia.mem.Buffer>;
}) error zx.Status;
};
应该对由某些外部可信来源定义的类型或值添加注释 并引用外部事物例如,引用 Wi-Fi 描述配置结构的规范同样,如果 结构必须与 C 头文件中定义的 ABI 匹配,请引用 C 头文件。
有关注释应包含的内容的详情,请参阅 API 文档评分准则。
引用 FIDL 协议或协议方法
在注释中引用 FIDL 协议或其方法时应遵循 格式:
/// See fuchsia.library/ProtocolName.Method for more information.
当引用与注释位于同一库中的协议时,库
ProtocolName.Method
。
同样,在使用与注释相同的协议引用方法时,
库名称和协议名称可以省略:Method
。
库概览
您可以以文档注释的形式提供库概览,
library
语句。“库”语句启动 FIDL 文件。例如:
/// Library containing example FIDL used throughout the Fuchsia documentation.
library fuchsia.examples.docs;
库概览应提供定义库的一般文档。 他们还可以详细说明各种讯息, 以及这些消息和协议如何协同使用。
虽然一个库可以细分为多个 FIDL 文件, 只能是单个库概览。建议你参考下面这些有关媒体库的建议 概览:
- 如果概览很短,并且库由单个文件组成,您可以
将概览放在库文件顶部的
library
语句中。 - 如果库包含多个文件,请创建一个独立的文件
overview.fidl
,用于为库编写文档。“overview.fidl”文件不应 包含任何声明、类型别名或协议定义。
非完整评论
如果您的评论是面向图书馆作者的,请使用更简单的评论 //
(两个正斜线),该符号不透过目标语言。
在决定常规 ///
注释和非 flow-through 注释时
请注意以下几点:
常规评论:
- 形参、实参和函数的说明
- 使用说明
非完整评论:
- 内部“待办事项”评论
- 版权通知
- 实现细节
这两种评论样式都可以结合使用:
/// A widget displaying violins on the screen.
// TODO -- widgets should use UUIDs instead of sequential ids
type ViolinWidget = struct {
/// A monotonically increasing id, uniquely identifying the widget.
id uint64;
/// Location of the top left corner of the widget.
location Point;
};
文件
库由一个或多个文件组成。这些文件存储在 目录层次结构:
fidl/<library>/[<dir>/]*<file>.fidl
<library>
目录使用以英文句点分隔的 FIDL 名称进行命名,
库。<dir>
子目录是可选的,通常不用于
包含不到十几个文件的库。此目录结构与
FIDL 文件包含在 Fuchsia SDK 中。
将库拆分为文件不会对 库。声明(包括协议)可以相互引用, 而不管它们显示在什么文件中。 将库拆分为多个文件,以最大限度地提高可读性。
- 对于库中的文件,首选 DAG 依赖关系图。
- 更喜欢让相互引用的定义在文字上彼此靠近, 最好在同一个文件中
- 对于复杂的库,最好在叶中定义纯数据类型或常量 文件,并定义在主干中引用这些类型的协议 文件。