項目27:パブリックインターフェイスのドキュメントを書こう
LT;DR
パブリック API にはドキュメントを書こう
コードからは分からないことを書こう
e.g.
panic(#Panics)が起こる条件
unsafe なコードが必要とする条件(#Safety)
意思決定(「なぜそうしたか」、「なぜそうしなかったか」) hr.icon
ある クレート が別のプログラマ(未来の自分も含む)に使われるのであれば、パブリック API のドキュメントを用意すること ドキュメントコメント
code:rs
/// 2 つの [BoundingBox] を正確に包含する [BoudingBox] を計算する
pub fn union(a: &BoundingBox, b: &BoundingBox) -> BoundingBox {
// ...
}
注意点
コードはコードフォントを使う(` で囲む)
以下のように書くことで、Something がスコープ内にあればそれに対する ハイパーリンク がドキュメントに付与される code:md
[Something]
#Examples セクションにサンプルコードを書く
warning.icon このコードは cargo test 時にコンパイルされ、実行される
#Panics セクションに panic を起こさないために必要な前提条件を書く
#Safety セクションに unsafe なコードが必要とする前提条件を書く
どう書くか困った際には、標準ライブラリを参考にすると良い
ドキュメントの生成
cargo doc を実行すると、ドキュメンテーションコメントからドキュメントを生成できる
ドキュメントを書いたら「レンダリングされたドキュメントを読もう」
読むには、--open または --no-deps --open(現在のクレートにドキュメントを限定する) オプションを付与する
関連する Lint 項目
code:rs
/// [Polygon] のバウンディングボックス
pub struct BoundingBox {
// ...
}
上記のコードは Polygon のドキュメントが無い場合に、警告を出す
code:_
warning: unresolved link to Polygon
--> docs/src/main.rs:4:30
|
4 | /// [Polygon] のバウンディングボックス
| ^^^^^^^^^ no item named Polygon in scope
warning.icon ドキュメントの品質が低下する危険性がある
ドキュメントを置く場所
ドキュメントは cargo doc の出力先(デフォルトでは target/doc)だが、別のディレクトリに置いても良い
e.g. examples サブディレクトリ
クレートを利用したバイナリコードを置く場所としてよく用いられる
tests/ ディレクトリ以下の統合テストも同様
公開されたクレートのドキュメント
docs.rs: cargo doc の出力のトップレベルページが表示される
トップレベルページは、src/lib.rs ファイルのトップレベルの //! コメント から生成される
crates.io: リポジトリのトップレベルの README.md
ドキュメントに書くべきでないこと
「コードから分かることはドキュメントに書かない」
これを書いてしまうと、コードとコメントとで 不整合 が起きやすくなる e.g. リファクタリング する際にコメントも変更する必要があるが、IDE 上では指摘されない e.g.
code:rs
/// 2 つの [BoundingBox] を正確に包含する [BoudingBox] の新しいインスタンスを返す
///
/// 引数:
/// - 'a': BoundingBox に対する不変参照
/// - 'b': BoundingBox に対する不変参照
/// 戻り値: 新しい BoundingBox インスタンス
pub fn union(a: &BoundingBox, b: &BoundingBox) -> BoundingBox {
code:rs
pub fn union(a: &mut BoundingBox, b: &BoundingBox) -> BoundingBox {
言い換えると、「コードから明らかでないことはすべて、ドキュメントに書こう」
メソッドを使用している他のコードについて書かない
e.g.
code:rs
/// 2 つの [BoundingBox] インスタンスの重なった部分を返す。
/// 重なりがなければ None を返す。
/// hits.rs 内の衝突判定コードが、object.overlap によるコストの高いピクセル単位のチェックを行う、
/// 事前チェックとしてこのメソッドを用いて 2 つのオブジェクトが重なるかどうかを判定する。
pub intersection(
a: &BoundingBox,
b: &BoundingBox,
) -> Option<BoundingBox> {
このようなコメントは、メソッドを使用するコード(hits.rs)を変更する際に 不整合 を起こす可能性が高い 改善案
code:rs
/// 2 つの [BoundingBox] インスタンスの重なった部分を返す。
/// 重なりがなければ None を返す。
/// バウンディングボックスに重なりがあるということは衝突の必要条件ではあるが十分条件ではないため、重なった部分に
/// 対してピクセル単位のチェックが必要。
コードを書く際のアドバイス「未来形でプログラミングを行おう」はドキュメントにも当てはまる
そのためには、コメントは 意思決定 に焦点を当てて記述すべきである