集册 Rust 中文教程 代码风格

代码风格

欢马劈雪     最近更新时间:2020-08-04 05:37:59

145

空白

  • 每行不能超出99个字符。
  • 缩进只用空格,不用TAB。
  • 行和文件末尾不要有空白。

空格

  • 二元运算符左右加空格,包括属性里的等号:
#[deprecated = "Use `bar` instead."]
fn foo(a: usize, b: usize) -> usize {
    a + b
}
  • 在分号和逗号后面加空格:
fn foo(a: Bar);

MyStruct { foo: 3, bar: 4 }

foo(bar, baz);
  • 在单行语句块或struct表达式的开始大括号之后和结束大括号之前加空格:
spawn(proc() { do_something(); })

Point { x: 0.1, y: 0.3 }

折行

  • 对于多行的函数签名,每个新行和第一个参数对齐。允许每行多个参数:
fn frobnicate(a: Bar, b: Bar,
              c: Bar, d: Bar)
              -> Bar {
    ...
}

fn foo<T: This,
       U: That>(
       a: Bar,
       b: Bar)
       -> Baz {
    ...
}
  • 多行函数调用一般遵循和签名统一的规则。然而,如果最后的参数开始了一个语句块,块的内容可以开始一个新行,缩进一层:
fn foo_bar(a: Bar, b: Bar,
           c: |Bar|) -> Bar {
    ...
}

// 可以在同一行:
foo_bar(x, y, |z| { z.transpose(y) });

// 也可以在新一行缩进函数体:
foo_bar(x, y, |z| {
    z.quux();
    z.rotate(x)
})

对齐

常见代码不必在行中用多余的空格来对齐。

// 好
struct Foo {
    short: f64,
    really_long: f64,
}

// 坏
struct Bar {
    short:       f64,
    really_long: f64,
}

// 好
let a = 0;
let radius = 7;

// 坏
let b        = 0;
let diameter = 7;

避免块注释

使用行注释:

// 等待主线程返回,并设置过程错误码
// 明显地。

而不是:

/*
 * 等待主线程返回,并设置过程错误码
 * 明显地。
 */

文档注释

文档注释前面加三个斜线(///)而且提示你希望将注释包含在 Rustdoc 的输出里。 它们支持 Markdown 语言 而且是注释你的公开API的主要方式。

支持的 markdown 功能包括列在 GitHub Flavored Markdown 文档中的所有扩展,加上上角标。

总结行

任何文档注释中的第一行应该是一行总结代码的单行短句。该行用于在 Rustdoc 输出中的一个简短的总结性描述,所以,让它短比较好。

句子结构

所有的文档注释,包括总结行,一个以大写字母开始,以句号、问号,或者感叹号结束。最好使用完整的句子而不是片段。

总结行应该以 第三人称单数陈述句形式 来写。 基本上,这意味着用 "Returns" 而不是 "Return"。

例如:

/// 根据编译器提供的参数,设置一个缺省的运行时配置。
///
/// 这个函数将阻塞直到整个 M:N 调度器池退出了。
/// 这个函数也要求一个本地的线程可用。
///
/// # 参数
///
/// * `argc` 和 `argv` - 参数向量。在 Unix 系统上,该信息被`os::args`使用。
///
/// * `main` - 运行在 M:N 调度器池内的初始过程。
///            一旦这个过程退出,调度池将开始关闭。
///            整个池(和这个函数)将只有在所有子线程完成执行后。
///
/// # 返回值
///
/// 返回值被用作进程返回码。成功是 0,101 是错误。

避免文档内注释

内嵌文档注释 只用于 注释 crates 和文件级的模块:

//! 核心库。
//!
//! 核心库是...

解释上下文

Rust 没有特定的构造器,只有返回新实例的函数。 这些在自动生成的类型文档中是不可见的,因此你应该专门链接到它们:

/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
/// These can be created through
/// [`iter.fuse()`](trait.Iterator.html#method.fuse).
pub struct Fuse<I> {
    // ...
}

开始的大括号总是出现的同一行。

fn foo() {
    ...
}

fn frobnicate(a: Bar, b: Bar,
              c: Bar, d: Bar)
              -> Bar {
    ...
}

trait Bar {
    fn baz(&self);
}

impl Bar for Baz {
    fn baz(&self) {
        ...
    }
}

frob(|x| {
    x.transpose()
})

match 分支有大括号,除非是单行表达式。

match foo {
    bar => baz,
    quux => {
        do_something();
        do_something_else()
    }
}

return 语句有分号。

fn foo() {
    do_something();

    if condition() {
        return;
    }

    do_something_else();
}

行尾的逗号

Foo { bar: 0, baz: 1 }

Foo {
    bar: 0,
    baz: 1,
}

match a_thing {
    None => 0,
    Some(x) => 1,
}

一般命名约定

通常,Rust 倾向于为“类型级”结构(类型和 traits)使用 CamelCase 而为“值级”结构使用 snake_case 。更确切的约定:

条目 约定
Crates snake_case (但倾向于单个词)
Modules snake_case
Types CamelCase
Traits CamelCase
Enum variants CamelCase
Functions snake_case
Methods snake_case
General constructors newwith_more_details
Conversion constructors from_some_other_type
Local variables snake_case
Static variables SCREAMING_SNAKE_CASE
Constant variables SCREAMING_SNAKE_CASE
Type parameters 简洁 CamelCase,通常单个大写字母:T
Lifetimes 短的小写: 'a
展开阅读全文