<sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/rust/coding-guidelinesmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_TW/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/it_IT/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ja_JP/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ko_KR/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/pt_BR/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/sp_SP/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhW/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/rust/coding-guidelines.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h)Documentation/rust/coding-guidelines.rst h]h)}(h(Documentation/rust/coding-guidelines.rsth]h(Documentation/rust/coding-guidelines.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhKubj)}(h-司延腾 Yanteng Si h]h)}(h,司延腾 Yanteng Si h](h司延腾 Yanteng Si <}(hj4hhhNhNubh reference)}(hsiyanteng@loongson.cnh]hsiyanteng@loongson.cn}(hj>hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:siyanteng@loongson.cnuh1j<hj4ubh>}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj0ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h 编码指南h]h 编码指南}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1johjlhhhhhK ubh)}(h7本文档描述了如何在内核中编写Rust代码。h]h7本文档描述了如何在内核中编写Rust代码。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjlhhubjk)}(hhh](jp)}(h风格和格式化h]h风格和格式化}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hX)代码应该使用 ``rustfmt`` 进行格式化。这样一来,一个不时为内核做贡献的人就不需要再去学 习和记忆一个样式指南了。更重要的是,审阅者和维护者不需要再花时间指出风格问题,这样就可以 减少补丁落地所需的邮件往返。h](h代码应该使用 }(hjhhhNhNubhliteral)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX  进行格式化。这样一来,一个不时为内核做贡献的人就不需要再去学 习和记忆一个样式指南了。更重要的是,审阅者和维护者不需要再花时间指出风格问题,这样就可以 减少补丁落地所需的邮件往返。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hW``rustfmt`` 不检查注释和文档的约定。因此,这些仍然需要照顾到。h]h)}(hjh](j)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhL 不检查注释和文档的约定。因此,这些仍然需要照顾到。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjhhhhhNubh)}(h使用 ``rustfmt`` 的默认设置。这意味着遵循Rust的习惯性风格。例如,缩进时使用4个空格而 不是制表符。h](h使用 }(hjhhhNhNubj)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhv 的默认设置。这意味着遵循Rust的习惯性风格。例如,缩进时使用4个空格而 不是制表符。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h在输入、保存或提交时告知编辑器/IDE进行格式化是很方便的。然而,如果因为某些原因需要在某 个时候重新格式化整个内核Rust的源代码,可以运行以下程序::h]h在输入、保存或提交时告知编辑器/IDE进行格式化是很方便的。然而,如果因为某些原因需要在某 个时候重新格式化整个内核Rust的源代码,可以运行以下程序:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(hmake LLVM=1 rustfmth]hmake LLVM=1 rustfmt}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hv也可以检查所有的东西是否都是格式化的(否则就打印一个差异),例如对于一个CI,用::h]hu也可以检查所有的东西是否都是格式化的(否则就打印一个差异),例如对于一个CI,用:}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hjhhubj)}(hmake LLVM=1 rustfmtcheckh]hmake LLVM=1 rustfmtcheck}hj1sbah}(h]h ]h"]h$]h&]hhuh1jhhhK#hjhhubh)}(h像内核其他部分的 ``clang-format`` 一样, ``rustfmt`` 在单个文件上工作,并且不需要 内核配置。有时,它甚至可以与破碎的代码一起工作。h](h像内核其他部分的 }(hj?hhhNhNubj)}(h``clang-format``h]h clang-format}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubh 一样, }(hj?hhhNhNubj)}(h ``rustfmt``h]hrustfmt}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj?ubht 在单个文件上工作,并且不需要 内核配置。有时,它甚至可以与破碎的代码一起工作。}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK%hjhhubjk)}(hhh](jp)}(h导入h]h导入}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1johjqhhhhhK)ubh)}(h``rustfmt`` 默认会以一种在合并和变基时容易产生冲突的方式格式化导入,因为在某些情况下 它会将多个条目合并到同一行。例如:h](j)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 默认会以一种在合并和变基时容易产生冲突的方式格式化导入,因为在某些情况下 它会将多个条目合并到同一行。例如:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK+hjqhhubj)}(h// Do not use this style. use crate::{ example1, example2::{example3, example4, example5}, example6, example7, example8::example9, };h]h// Do not use this style. use crate::{ example1, example2::{example3, example4, example5}, example6, example7, example8::example9, };}hjsbah}(h]h ]h"]h$]h&]hhƌforcelanguagerusthighlight_args}uh1jhhhK.hjqhhubh)}(h3相反,内核使用如下所示的垂直布局:h]h3相反,内核使用如下所示的垂直布局:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjqhhubj)}(huse crate::{ example1, example2::{ example3, example4, example5, // }, example6, example7, example8::example9, // };h]huse crate::{ example1, example2::{ example3, example4, example5, // }, example6, example7, example8::example9, // };}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhK:hjqhhubh)}(hZ也就是说,每个条目占一行,只要列表中有多个条目就使用花括号。h]hZ也就是说,每个条目占一行,只要列表中有多个条目就使用花括号。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjqhhubh)}(hX末尾的空注释可以保留这种格式。不仅如此, ``rustfmt`` 在添加空注释后实际上会将导入重 新格式化为垂直布局。也就是说,可以通过对如下输入运行 ``rustfmt`` 来轻松地将原始示例 重新格式化为预期的风格:h](h=末尾的空注释可以保留这种格式。不仅如此, }(hjhhhNhNubj)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh~ 在添加空注释后实际上会将导入重 新格式化为垂直布局。也就是说,可以通过对如下输入运行 }(hjhhhNhNubj)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhA 来轻松地将原始示例 重新格式化为预期的风格:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKJhjqhhubj)}(h// Do not use this style. use crate::{ example1, example2::{example3, example4, example5, // }, example6, example7, example8::example9, // };h]h// Do not use this style. use crate::{ example1, example2::{example3, example4, example5, // }, example6, example7, example8::example9, // };}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKNhjqhhubh)}(h末尾的空注释适用于嵌套导入(如上所示)以及单条目导入——这有助于最小化补丁系列中的差 异:h]h末尾的空注释适用于嵌套导入(如上所示)以及单条目导入——这有助于最小化补丁系列中的差 异:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKYhjqhhubj)}(h use crate::{ example1, // };h]h use crate::{ example1, // };}hj-sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhK\hjqhhubh)}(hX末尾的空注释可以放在花括号内的任何一行中,但建议放在最后一个条目上,因为这让人联想到其 他格式化工具中的末尾逗号。有时在补丁系列中由于列表的变更,避免多次移动注释可能更简单。h]hX末尾的空注释可以放在花括号内的任何一行中,但建议放在最后一个条目上,因为这让人联想到其 他格式化工具中的末尾逗号。有时在补丁系列中由于列表的变更,避免多次移动注释可能更简单。}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhjqhhubh)}(h在某些情况下可能需要例外处理,即以上都不是硬性规则。也有一些代码尚未迁移到这种风格,但 请不要引入其他风格的代码。h]h在某些情况下可能需要例外处理,即以上都不是硬性规则。也有一些代码尚未迁移到这种风格,但 请不要引入其他风格的代码。}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjqhhubh)}(h最终目标是让 ``rustfmt`` 在稳定版本中自动支持这种格式化风格(或类似的风格),而无需 末尾的空注释。因此,在某个时候,目标是移除这些注释。h](h最终目标是让 }(hjYhhhNhNubj)}(h ``rustfmt``h]hrustfmt}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jhjYubh 在稳定版本中自动支持这种格式化风格(或类似的风格),而无需 末尾的空注释。因此,在某个时候,目标是移除这些注释。}(hjYhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhjqhhubeh}(h]id3ah ]h"]导入ah$]h&]uh1jjhjhhhhhK)ubeh}(h]id2ah ]h"]风格和格式化ah$]h&]uh1jjhjlhhhhhKubjk)}(hhh](jp)}(h注释h]h注释}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKmubh)}(hX*“普通”注释(即以 ``//`` 开头,而不是 ``///`` 或 ``//!`` 开头的代码文档)的写法与文 档注释相同,使用Markdown语法,尽管它们不会被渲染。这提高了一致性,简化了规则,并允许在 这两种注释之间更容易地移动内容。比如说:h](h“普通”注释(即以 }(hjhhhNhNubj)}(h``//``h]h//}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 开头,而不是 }(hjhhhNhNubj)}(h``///``h]h///}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 或 }(hjhhhNhNubj)}(h``//!``h]h//!}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 开头的代码文档)的写法与文 档注释相同,使用Markdown语法,尽管它们不会被渲染。这提高了一致性,简化了规则,并允许在 这两种注释之间更容易地移动内容。比如说:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKohjhhubj)}(h2// `object` is ready to be handled now. f(object);h]h2// `object` is ready to be handled now. f(object);}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKshjhhubh)}(h此外,就像文档一样,注释在句子的开头要大写,并以句号结束(即使是单句)。这包括 ``// SAFETY:``, ``// TODO:`` 和其他“标记”的注释,例如:h](hv此外,就像文档一样,注释在句子的开头要大写,并以句号结束(即使是单句)。这包括 }(hjhhhNhNubj)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, }(hjhhhNhNubj)}(h ``// TODO:``h]h// TODO:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) 和其他“标记”的注释,例如:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKxhjhhubj)}(h/// FIXME: The error should be handled properly.h]h/// FIXME: The error should be handled properly.}hj sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhK{hjhhubh)}(hX注释不应该被用于文档的目的:注释是为了实现细节,而不是为了用户。即使源文件的读者既是API 的实现者又是用户,这种区分也是有用的。事实上,有时同时使用注释和文档是很有用的。例如,用 于 ``TODO`` 列表或对文档本身的注释。对于后一种情况,注释可以插在中间;也就是说,离要注 释的文档行更近。对于其他情况,注释会写在文档之后,例如:h](hX 注释不应该被用于文档的目的:注释是为了实现细节,而不是为了用户。即使源文件的读者既是API 的实现者又是用户,这种区分也是有用的。事实上,有时同时使用注释和文档是很有用的。例如,用 于 }(hj0hhhNhNubj)}(h``TODO``h]hTODO}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0ubh 列表或对文档本身的注释。对于后一种情况,注释可以插在中间;也就是说,离要注 释的文档行更近。对于其他情况,注释会写在文档之后,例如:}(hj0hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h/// Returns a new [`Foo`]. /// /// # Examples /// // TODO: Find a better example. /// ``` /// let foo = f(42); /// ``` // FIXME: Use fallible approach. pub fn f(x: i32) -> Foo { // ... }h]h/// Returns a new [`Foo`]. /// /// # Examples /// // TODO: Find a better example. /// ``` /// let foo = f(42); /// ``` // FIXME: Use fallible approach. pub fn f(x: i32) -> Foo { // ... }}hjPsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhjhhubh)}(hX这适用于公共和私有项目。这增加了与公共项目的一致性,允许在更改可见性时减少涉及的更改, 并允许我们将来也为私有项目生成文档。换句话说,如果为私有项目编写了文档,那么仍然应该使 用 ``///`` 。例如:h](hX这适用于公共和私有项目。这增加了与公共项目的一致性,允许在更改可见性时减少涉及的更改, 并允许我们将来也为私有项目生成文档。换句话说,如果为私有项目编写了文档,那么仍然应该使 用 }(hj`hhhNhNubj)}(h``///``h]h///}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj`ubh 。例如:}(hj`hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h//// My private function. // TODO: ... fn f() {}h]h//// My private function. // TODO: ... fn f() {}}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhjhhubh)}(h一种特殊的注释是 ``// SAFETY:`` 注释。这些注释必须出现在每个 ``unsafe`` 块之前,它们 解释了为什么该块内的代码是正确/健全的,即为什么它在任何情况下都不会触发未定义行为,例如:h](h一种特殊的注释是 }(hjhhhNhNubj)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, 注释。这些注释必须出现在每个 }(hjhhhNhNubj)}(h ``unsafe``h]hunsafe}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 块之前,它们 解释了为什么该块内的代码是正确/健全的,即为什么它在任何情况下都不会触发未定义行为,例如:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hF// SAFETY: `p` is valid by the safety requirements. unsafe { *p = 0; }h]hF// SAFETY: `p` is valid by the safety requirements. unsafe { *p = 0; }}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhjhhubh)}(hXX``// SAFETY:`` 注释不能与代码文档中的 ``# Safety`` 部分相混淆。 ``# Safety`` 部 分指定了(函数)调用者或(特性)实现者需要遵守的契约。 ``// SAFETY:`` 注释显示了为什么一个(函数)调用者或(特性)实现者实际上尊重了 ``# Safety`` 部分或语言参考中的前提条件。h](j)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh# 注释不能与代码文档中的 }(hjhhhNhNubj)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 部分相混淆。 }(hjhhhNhNubj)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhW 部 分指定了(函数)调用者或(特性)实现者需要遵守的契约。 }(hjhhhNhNubj)}(h``// SAFETY:``h]h // SAFETY:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh_ 注释显示了为什么一个(函数)调用者或(特性)实现者实际上尊重了 }(hjhhhNhNubj)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ 部分或语言参考中的前提条件。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id4ah ]h"]注释ah$]h&]uh1jjhjlhhhhhKmubjk)}(hhh](jp)}(h 代码文档h]h 代码文档}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1johj>hhhhhKubh)}(hRust内核代码不像C内核代码那样被记录下来(即通过kernel-doc)。取而代之的是用于记录Rust 代码的常用系统:rustdoc工具,它使用Markdown(一种轻量级的标记语言)。h]hRust内核代码不像C内核代码那样被记录下来(即通过kernel-doc)。取而代之的是用于记录Rust 代码的常用系统:rustdoc工具,它使用Markdown(一种轻量级的标记语言)。}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh)}(h5要学习Markdown,外面有很多指南。例如:h]h5要学习Markdown,外面有很多指南。例如:}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh)}(hhttps://commonmark.org/help/h]j=)}(hjmh]hhttps://commonmark.org/help/}(hjohhhNhNubah}(h]h ]h"]h$]h&]refurijmuh1j<hjkubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh)}(h2一个记录良好的Rust函数可能是这样的:h]h2一个记录良好的Rust函数可能是这样的:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubj)}(hX/// Returns the contained [`Some`] value, consuming the `self` value, /// without checking that the value is not [`None`]. /// /// # Safety /// /// Calling this method on [`None`] is *[undefined behavior]*. /// /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples /// /// ``` /// let x = Some("air"); /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); /// ``` pub unsafe fn unwrap_unchecked(self) -> T { match self { Some(val) => val, // SAFETY: The safety contract must be upheld by the caller. None => unsafe { hint::unreachable_unchecked() }, } }h]hX/// Returns the contained [`Some`] value, consuming the `self` value, /// without checking that the value is not [`None`]. /// /// # Safety /// /// Calling this method on [`None`] is *[undefined behavior]*. /// /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// /// # Examples /// /// ``` /// let x = Some("air"); /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); /// ``` pub unsafe fn unwrap_unchecked(self) -> T { match self { Some(val) => val, // SAFETY: The safety contract must be upheld by the caller. None => unsafe { hint::unreachable_unchecked() }, } }}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhj>hhubh)}(hS这个例子展示了一些 ``rustdoc`` 的特性和内核中遵循的一些惯例:h](h这个例子展示了一些 }(hjhhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, 的特性和内核中遵循的一些惯例:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh bullet_list)}(hhh](h list_item)}(h第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额 外的段落中。 h]h)}(h第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额 外的段落中。h]h第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额 外的段落中。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hN不安全的函数必须在 ``# Safety`` 部分记录其安全前提条件。 h]h)}(hM不安全的函数必须在 ``# Safety`` 部分记录其安全前提条件。h](h不安全的函数必须在 }(hjhhhNhNubj)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh% 部分记录其安全前提条件。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXY虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 ``# Panics`` 部分描述发 生这种情况的条件。 请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下, 都应该使用一个可失败的方法,通常是返回一个 ``Result``。 h](h)}(h虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 ``# Panics`` 部分描述发 生这种情况的条件。h](hR虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 }(hjhhhNhNubj)}(h ``# Panics``h]h# Panics}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, 部分描述发 生这种情况的条件。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubh)}(h请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下, 都应该使用一个可失败的方法,通常是返回一个 ``Result``。h](h请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下, 都应该使用一个可失败的方法,通常是返回一个 }(hj.hhhNhNubj)}(h ``Result``h]hResult}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj.ubh。}(hj.hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hf如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。 h]h)}(he如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。h]he如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjTubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(htRust项目(函数、类型、常量……)必须有适当的链接(``rustdoc`` 会自动创建一个 链接)。 h]h)}(hsRust项目(函数、类型、常量……)必须有适当的链接(``rustdoc`` 会自动创建一个 链接)。h](hGRust项目(函数、类型、常量……)必须有适当的链接(}(hjphhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjpubh! 会自动创建一个 链接)。}(hjphhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjlubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXP任何 ``unsafe`` 的代码块都必须在前面加上一个 ``// SAFETY:`` 的注释,描述里面 的代码为什么是正确的。 虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法, 最重要的是,它提供了一种知道没有额外隐含约束的方法。 h](h)}(h任何 ``unsafe`` 的代码块都必须在前面加上一个 ``// SAFETY:`` 的注释,描述里面 的代码为什么是正确的。h](h任何 }(hjhhhNhNubj)}(h ``unsafe``h]hunsafe}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh, 的代码块都必须在前面加上一个 }(hjhhhNhNubj)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh; 的注释,描述里面 的代码为什么是正确的。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(h虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法, 最重要的是,它提供了一种知道没有额外隐含约束的方法。h]h虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法, 最重要的是,它提供了一种知道没有额外隐含约束的方法。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhj>hhubh)}(hl要了解更多关于如何编写Rust和拓展功能的文档,请看看 ``rustdoc`` 这本书,网址是:h](hJ要了解更多关于如何编写Rust和拓展功能的文档,请看看 }(hjhhhNhNubj)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 这本书,网址是:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubh block_quote)}(hBhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.html h]h)}(hAhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.htmlh]j=)}(hjh]hAhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.html}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1j<hjubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhhhKhj>hhubh)}(hr此外,内核支持通过在链接目标前添加 ``srctree/`` 来创建相对于源代码树的链接。例如:h](h4此外,内核支持通过在链接目标前添加 }(hj,hhhNhNubj)}(h ``srctree/``h]hsrctree/}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,ubh2 来创建相对于源代码树的链接。例如:}(hj,hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubj)}(hH//! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)h]hH//! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)}hjLsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhj>hhubh)}(h或者:h]h或者:}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj>hhubj)}(h3/// [`struct mutex`]: srctree/include/linux/mutex.hh]h3/// [`struct mutex`]: srctree/include/linux/mutex.h}hjjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhKhj>hhubeh}(h]id5ah ]h"] 代码文档ah$]h&]uh1jjhjlhhhhhKubjk)}(hhh](jp)}(h C FFI 类型h]h C FFI 类型}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhKubh)}(hXRust 内核代码使用类型别名(如 ``c_int``)来引用 C 类型(如 ``int``),这些别名可 以直接从 ``kernel`` 预导入(prelude)中获取。请不要使用 ``core::ffi`` 中的别 名——它们可能无法映射到正确的类型。h](h*Rust 内核代码使用类型别名(如 }(hjhhhNhNubj)}(h ``c_int``h]hc_int}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh)来引用 C 类型(如 }(hjhhhNhNubj)}(h``int``h]hint}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh#),这些别名可 以直接从 }(hjhhhNhNubj)}(h ``kernel``h]hkernel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh3 预导入(prelude)中获取。请不要使用 }(hjhhhNhNubj)}(h ``core::ffi``h]h core::ffi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhA 中的别 名——它们可能无法映射到正确的类型。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hZ这些别名通常应该直接通过其标识符引用,即作为单段路径。例如:h]hZ这些别名通常应该直接通过其标识符引用,即作为单段路径。例如:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(h.fn f(p: *const c_char) -> c_int { // ... }h]h.fn f(p: *const c_char) -> c_int { // ... }}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMhjhhubeh}(h]c-ffiah ]h"] c ffi 类型ah$]h&]uh1jjhjlhhhhhKubjk)}(hhh](jp)}(h命名h]h命名}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhM ubh)}(h0Rust内核代码遵循通常的Rust命名空间:h]h0Rust内核代码遵循通常的Rust命名空间:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjhhubj )}(h7https://rust-lang.github.io/api-guidelines/naming.html h]h)}(h6https://rust-lang.github.io/api-guidelines/naming.htmlh]j=)}(hj4h]h6https://rust-lang.github.io/api-guidelines/naming.html}(hj6hhhNhNubah}(h]h ]h"]h$]h&]refurij4uh1j<hj2ubah}(h]h ]h"]h$]h&]uh1hhhhMhj.ubah}(h]h ]h"]h$]h&]uh1jhhhMhjhhubh)}(hX,当现有的C语言概念(如宏、函数、对象......)被包装成Rust抽象时,应该使用尽可能接近C语 言的名称,以避免混淆,并在C语言和Rust语言之间来回切换时提高可读性。例如,C语言中的 ``pr_info`` 这样的宏在Rust中的命名是一样的。h](h当现有的C语言概念(如宏、函数、对象......)被包装成Rust抽象时,应该使用尽可能接近C语 言的名称,以避免混淆,并在C语言和Rust语言之间来回切换时提高可读性。例如,C语言中的 }(hjPhhhNhNubj)}(h ``pr_info``h]hpr_info}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjPubh/ 这样的宏在Rust中的命名是一样的。}(hjPhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h说到这里,应该调整大小写以遵循Rust的命名惯例,模块和类型引入的命名间隔不应该在项目名称 中重复。例如,在包装常量时,如:h]h说到这里,应该调整大小写以遵循Rust的命名惯例,模块和类型引入的命名间隔不应该在项目名称 中重复。例如,在包装常量时,如:}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hC#define GPIO_LINE_DIRECTION_IN 0 #define GPIO_LINE_DIRECTION_OUT 1h]hC#define GPIO_LINE_DIRECTION_IN 0 #define GPIO_LINE_DIRECTION_OUT 1}hj~sbah}(h]h ]h"]h$]h&]hhjjcj}uh1jhhhMhjhhubh)}(h>在Rust中的等价物可能是这样的(忽略文档)。:h]h>在Rust中的等价物可能是这样的(忽略文档)。:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hpub mod gpio { pub enum LineDirection { In = bindings::GPIO_LINE_DIRECTION_IN as _, Out = bindings::GPIO_LINE_DIRECTION_OUT as _, } }h]hpub mod gpio { pub enum LineDirection { In = bindings::GPIO_LINE_DIRECTION_IN as _, Out = bindings::GPIO_LINE_DIRECTION_OUT as _, } }}hjsbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMhjhhubh)}(h也就是说, ``GPIO_LINE_DIRECTION_IN`` 的等价物将被称为 ``gpio::LineDirection::In`` 。 特别是,它不应该被命名为 ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN`` 。h](h也就是说, }(hjhhhNhNubj)}(h``GPIO_LINE_DIRECTION_IN``h]hGPIO_LINE_DIRECTION_IN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 的等价物将被称为 }(hjhhhNhNubj)}(h``gpio::LineDirection::In``h]hgpio::LineDirection::In}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh* 。 特别是,它不应该被命名为 }(hjhhhNhNubj)}(h5``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``h]h1gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM(hjhhubeh}(h]id6ah ]h"]命名ah$]h&]uh1jjhjlhhhhhM ubjk)}(hhh](jp)}(h代码检查提示(Lints)h]h代码检查提示(Lints)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1johjhhhhhM-ubh)}(h在 Rust 中,可以在局部 ``allow`` 特定的警告(诊断信息、代码检查提示(lint)), 使编译器忽略给定函数、模块、代码块等中给定警告的实例。h](h在 Rust 中,可以在局部 }(hj hhhNhNubj)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 特定的警告(诊断信息、代码检查提示(lint)), 使编译器忽略给定函数、模块、代码块等中给定警告的实例。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM/hjhhubh)}(hU这类似于 C 中的 ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` [#]_:h](h这类似于 C 中的 }(hj) hhhNhNubj)}(h``#pragma GCC diagnostic push``h]h#pragma GCC diagnostic push}(hj1 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj) ubh + }(hj) hhhNhNubj)}(h ``ignored``h]hignored}(hjC hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj) ubh + }hj) sbj)}(h``pop``h]hpop}(hjU hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj) ubh }(hj) hhhNhNubhfootnote_reference)}(h[#]_h]h1}(hji hhhNhNubah}(h]id7ah ]h"]h$]h&]autoKrefidid8docname)translations/zh_CN/rust/coding-guidelinesuh1jg hj) resolvedKubh:}(hj) hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM2hjhhubj)}(h#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static void f(void) {} #pragma GCC diagnostic poph]h#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static void f(void) {} #pragma GCC diagnostic pop}hj sbah}(h]h ]h"]h$]h&]hhjjjj}uh1jhhhM5hjhhubhfootnote)}(h在这个特定情况下,可以使用内核的 ``__{always,maybe}_unused`` 属性 (C23 的 ``[[maybe_unused]]``);然而,此示例旨在反映下文讨论的 Rust 中 的等效代码检查提示。 h](hlabel)}(hhh]h1}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj hhhNhNubh)}(h在这个特定情况下,可以使用内核的 ``__{always,maybe}_unused`` 属性 (C23 的 ``[[maybe_unused]]``);然而,此示例旨在反映下文讨论的 Rust 中 的等效代码检查提示。h](h1在这个特定情况下,可以使用内核的 }(hj hhhNhNubj)}(h``__{always,maybe}_unused``h]h__{always,maybe}_unused}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 属性 (C23 的 }(hj hhhNhNubj)}(h``[[maybe_unused]]``h]h[[maybe_unused]]}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh[);然而,此示例旨在反映下文讨论的 Rust 中 的等效代码检查提示。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM<hj ubeh}(h]jz ah ]h"]1ah$]h&]js ajx Kj{ j| uh1j hhhM<hjhhubh)}(h但要简洁得多:h]h但要简洁得多:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM@hjhhubj)}(h#[allow(dead_code)] fn f() {}h]h#[allow(dead_code)] fn f() {}}hj sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMBhjhhubh)}(h凭借这一点,可以更方便地默认启用更多诊断(即在 ``W=`` 级别之外)。特别是那些可能有 一些误报但在其他方面非常有用的诊断,保持启用可以捕获潜在的错误。h](hF凭借这一点,可以更方便地默认启用更多诊断(即在 }(hj hhhNhNubj)}(h``W=``h]hW=}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 级别之外)。特别是那些可能有 一些误报但在其他方面非常有用的诊断,保持启用可以捕获潜在的错误。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMGhjhhubh)}(h在此基础上,Rust 提供了 ``expect`` 属性,更进一步。如果警告没有产生,它会让编译器 发出警告。例如,以下代码将确保当 ``f()`` 在某处被调用时,我们必须移除该属性:h](h!在此基础上,Rust 提供了 }(hj# hhhNhNubj)}(h ``expect``h]hexpect}(hj+ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj# ubhx 属性,更进一步。如果警告没有产生,它会让编译器 发出警告。例如,以下代码将确保当 }(hj# hhhNhNubj)}(h``f()``h]hf()}(hj= hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj# ubh7 在某处被调用时,我们必须移除该属性:}(hj# hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMJhjhhubj)}(h#[expect(dead_code)] fn f() {}h]h#[expect(dead_code)] fn f() {}}hjU sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMMhjhhubh)}(h5如果我们不这样做,编译器会发出警告::h]h4如果我们不这样做,编译器会发出警告:}(hje hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMRhjhhubj)}(hwarning: this lint expectation is unfulfilled --> x.rs:3:10 | 3 | #[expect(dead_code)] | ^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by defaulth]hwarning: this lint expectation is unfulfilled --> x.rs:3:10 | 3 | #[expect(dead_code)] | ^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by default}hjs sbah}(h]h ]h"]h$]h&]hhuh1jhhhMThjhhubh)}(hc这意味着 ``expect`` 不会在不需要时被遗忘,这可能发生在以下几种情况中:h](h 这意味着 }(hj hhhNhNubj)}(h ``expect``h]hexpect}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhL 不会在不需要时被遗忘,这可能发生在以下几种情况中:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM\hjhhubj)}(hhh](j)}(h(开发过程中添加的临时属性。 h]h)}(h'开发过程中添加的临时属性。h]h'开发过程中添加的临时属性。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM^hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hY编译器、Clippy 或自定义工具中代码检查提示的改进可能消除误报。 h]h)}(hX编译器、Clippy 或自定义工具中代码检查提示的改进可能消除误报。h]hX编译器、Clippy 或自定义工具中代码检查提示的改进可能消除误报。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM`hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h|当代码检查提示不再需要时,因为预期它会在某个时候被移除,例如上面的 ``dead_code`` 示例。 h]h)}(h{当代码检查提示不再需要时,因为预期它会在某个时候被移除,例如上面的 ``dead_code`` 示例。h](hd当代码检查提示不再需要时,因为预期它会在某个时候被移除,例如上面的 }(hj hhhNhNubj)}(h ``dead_code``h]h dead_code}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 示例。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMbhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhM^hjhhubh)}(hP这也增加了剩余 ``allow`` 的可见性,并减少了误用的可能性。h](h这也增加了剩余 }(hj hhhNhNubj)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh1 的可见性,并减少了误用的可能性。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMehjhhubh)}(h@因此,优先使用 ``expect`` 而不是 ``allow``,除非:h](h因此,优先使用 }(hj$ hhhNhNubj)}(h ``expect``h]hexpect}(hj, hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ ubh 而不是 }(hj$ hhhNhNubj)}(h ``allow``h]hallow}(hj> hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj$ ubh ,除非:}(hj$ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMghjhhubj)}(hhh](j)}(hX条件编译在某些情况下触发警告,在其他情况下不触发。 如果与总的相比,只有少数情况触发(或不触发)警告,那么可以考虑使用条件 ``expect``(即 ``cfg_attr(..., expect(...))``)。否则,使用 ``allow`` 可 能更简单。 h](h)}(hK条件编译在某些情况下触发警告,在其他情况下不触发。h]hK条件编译在某些情况下触发警告,在其他情况下不触发。}(hj] hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMihjY ubh)}(h如果与总的相比,只有少数情况触发(或不触发)警告,那么可以考虑使用条件 ``expect``(即 ``cfg_attr(..., expect(...))``)。否则,使用 ``allow`` 可 能更简单。h](hj如果与总的相比,只有少数情况触发(或不触发)警告,那么可以考虑使用条件 }(hjk hhhNhNubj)}(h/``expect``(即 ``cfg_attr(..., expect(...))``h]h+expect``(即 ``cfg_attr(..., expect(...))}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjk ubh)。否则,使用 }(hjk hhhNhNubj)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjk ubh 可 能更简单。}(hjk hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMkhjY ubeh}(h]h ]h"]h$]h&]uh1jhjV hhhhhNubj)}(h|在宏内部,不同的调用可能会创建在某些情况下触发警告而在其他情况下不触发的展开代码。 h]h)}(h{在宏内部,不同的调用可能会创建在某些情况下触发警告而在其他情况下不触发的展开代码。h]h{在宏内部,不同的调用可能会创建在某些情况下触发警告而在其他情况下不触发的展开代码。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMohj ubah}(h]h ]h"]h$]h&]uh1jhjV hhhhhNubj)}(h|当代码可能在某些架构上触发警告但在其他架构上不触发时,例如到 C FFI 类型的 ``as`` 转换。 h]h)}(h{当代码可能在某些架构上触发警告但在其他架构上不触发时,例如到 C FFI 类型的 ``as`` 转换。h](hk当代码可能在某些架构上触发警告但在其他架构上不触发时,例如到 C FFI 类型的 }(hj hhhNhNubj)}(h``as``h]has}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 转换。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMqhj ubah}(h]h ]h"]h$]h&]uh1jhjV hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhMihjhhubh)}(h6作为一个更详细的示例,考虑以下程序:h]h6作为一个更详细的示例,考虑以下程序:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMthjhhubj)}(h6fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]h6fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMvhjhhubh)}(ht这里,如果 ``CONFIG_X`` 未设置,函数 ``g()`` 是死代码。我们可以在这里使用 ``expect`` 吗?h](h这里,如果 }(hj hhhNhNubj)}(h ``CONFIG_X``h]hCONFIG_X}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 未设置,函数 }(hj hhhNhNubj)}(h``g()``h]hg()}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh, 是死代码。我们可以在这里使用 }(hj hhhNhNubj)}(h ``expect``h]hexpect}(hj5 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 吗?}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hK#[expect(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hK#[expect(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hjM sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMhjhhubh)}(h如果 ``CONFIG_X`` 被设置,这将产生代码检查提示,因为在该配置中它不是死代码。因 此,在这种情况下,我们不能直接使用 ``expect``。h](h如果 }(hj] hhhNhNubj)}(h ``CONFIG_X``h]hCONFIG_X}(hje hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj] ubh 被设置,这将产生代码检查提示,因为在该配置中它不是死代码。因 此,在这种情况下,我们不能直接使用 }(hj] hhhNhNubj)}(h ``expect``h]hexpect}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj] ubh。}(hj] hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h.一个简单的可能性是使用 ``allow``:h](h"一个简单的可能性是使用 }(hj hhhNhNubj)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hJ#[allow(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hJ#[allow(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMhjhhubh)}(h,另一种方法是使用条件 ``expect``:h](h另一种方法是使用条件 }(hj hhhNhNubj)}(h ``expect``h]hexpect}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hd#[cfg_attr(not(CONFIG_X), expect(dead_code))] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hd#[cfg_attr(not(CONFIG_X), expect(dead_code))] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhjjrustj}uh1jhhhMhjhhubh)}(h这将确保如果有人在某处引入了对 ``g()`` 的另一个调用(例如无条件的),那么将会被发现 它不再是死代码。然而, ``cfg_attr`` 比简单的 ``allow`` 更复杂。h](h.这将确保如果有人在某处引入了对 }(hj hhhNhNubj)}(h``g()``h]hg()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhf 的另一个调用(例如无条件的),那么将会被发现 它不再是死代码。然而, }(hj hhhNhNubj)}(h ``cfg_attr``h]hcfg_attr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 比简单的 }(hj hhhNhNubj)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh 更复杂。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h因此,当涉及多个配置或者代码检查提示可能由于非局部更改(如 ``dead_code``)而触发 时,使用条件 ``expect`` 可能不值得。h](hX因此,当涉及多个配置或者代码检查提示可能由于非局部更改(如 }(hj3 hhhNhNubj)}(h ``dead_code``h]h dead_code}(hj; hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3 ubh )而触发 时,使用条件 }(hj3 hhhNhNubj)}(h ``expect``h]hexpect}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj3 ubh 可能不值得。}(hj3 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h3有关 Rust 中诊断的更多信息,请参阅:h]h3有关 Rust 中诊断的更多信息,请参阅:}(hje hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj )}(hGhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.html h]h)}(hFhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.htmlh]j=)}(hjy h]hFhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.html}(hj{ hhhNhNubah}(h]h ]h"]h$]h&]refurijy uh1j<hjw ubah}(h]h ]h"]h$]h&]uh1hhhhMhjs ubah}(h]h ]h"]h$]h&]uh1jhhhMhjhhubeh}(h]lintsah ]h"]代码检查提示(lints)ah$]h&]uh1jjhjlhhhhhM-ubjk)}(hhh](jp)}(h 错误处理h]h 错误处理}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1johj hhhhhMubh)}(hI有关 Rust for Linux 特定错误处理的背景和指南,请参阅:h]hI有关 Rust for Linux 特定错误处理的背景和指南,请参阅:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj )}(hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rusth]h)}(hj h]j=)}(hj h]hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1j<hj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhhhMhj hhubeh}(h]id9ah ]h"] 错误处理ah$]h&]uh1jjhjlhhhhhMubeh}(h]id1ah ]h"] 编码指南ah$]h&]uh1jjhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(joN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}jz ]ji asnameids}(j j jjj~j{j;j8jj|j j jjj j j j j jz u nametypes}(j jj~j;jj jj j j uh}(j jljjj{jqj8jj|j>j jjjj jjs ji jz j j j u footnote_refs} citation_refs} autofootnotes]j aautofootnote_refs]ji asymbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jK sRparse_messages]transform_messages] transformerN include_log];Documentation/translations/zh_CN/rust/coding-guidelines.rst(NNNNta decorationNhhub.