RustFmt
RustFmtは、Rustのソースファイルを成形(フォーマット)するツールです。
パッケージ内の全てのファイルの成形、ファイル単独での成形ができますが、通常はパッケージ全体を処理することの方が多いでしょう。このツールは、Rustのコーディングスタイルを包括的に定めた「Rust Style Guide」(スタイルガイド)に準拠しています。手元から離れるソースファイルは、RustFmtを通してからにするのがマナーとも言えます。
RustFmtは、基本的にCargo経由で以下のように実行します。
% cargo fmt CargoパッケージマネージャからRustFmtを起動する
スタイルガイドは、エディションごとに定められており、「スタイルエディション」と呼ばれます。Cargoから実行するときには、パッケージのCargo.tomlファイル(editionキー)にRustエディションを記述し、これをスタイルエディションと見なしてソースファイルを成形します。
フォーマットルールの修正
Rust 2024では、いくつかのフォーマットルールが改善され、より開発者の期待に沿うような成形が実施されるようになりました。
ルールの変更は多岐にわたるので、基本的で影響範囲の大きそうな修正をピックアップして紹介します。
行末にコメントのある行の次の行のコメントを無意味に揃えない
少し複雑なのですが、従来は、行末にコメントのある行が存在する場合、かつ次の行がコメントのみの行である場合に、コメントで位置を揃えていました。
例えば、以下のリストは、従来下側のリストのように揃えられていました。
const MASK1: u16 = 0x0001; // マスク1 const MASK2: u16 = 0x0010; // マスク2 const MASK3: u16 = 0x0100; // マスク3 //const MASK4: u16 = 0x1000; // マスク4
↓
const MASK1: u16 = 0x0001; // マスク1 const MASK2: u16 = 0x0010; // マスク2 const MASK3: u16 = 0x0100; // マスク3 //const MASK4: u16 = 0x1000; // マスク4
最後の行のコメント位置は、期待するものでないので、Rust 2024では以下のように改善されています。
const MASK1: u16 = 0x0001; // マスク1 const MASK2: u16 = 0x0010; // マスク2 const MASK3: u16 = 0x0100; // マスク3 //const MASK4: u16 = 0x1000; // マスク4
コメント内の文字列をインデントしない
複数行コメント(/* ~ */)内の文字列は、本来はインデントなどの修正は不要なはずですが、従来はこれを行っていました。
例えば以下のリストの場合、従来は複数行コメントの中が揃うようにインデントされてしまい、コメントアウトを解除した場合に余計な空白が文字列に入ってしまいます。
Rust 2024では元の内容がそのまま保持されるようになりました。
fn main() { /* let s = String::from( " こんにちは、 世界! " ); */ }
↓
fn main() { /* let s = String::from( " こんにちは、 世界! " ); */ }
長い文字列リテラルがある場合でも式の成形が妨げられない
従来は、とても長い文字列リテラルがある場合に周辺の成形が実施されないことがありました。Rust 2024では、このような文字列が存在する場合でも成形がうまくいくように改善されています。
fn sub() { let value = if x == "じゅげむ じゅげむ ごこうのすりきれ かいじゃりすいぎょの すいぎょうまつ うんらいまつ ふうらいまつ くうねるところにすむところ やぶらこうじのぶらこうじ ぱいぽ ぱいぽ ぱいぽのしゅーりんがん しゅーりんがんのぐーりんだい ぐーりんだいのぽんぽこぴーの ぽんぽこなーの ちょうきゅうめいのちょうすけ" { true } else {false}; }
↓
fn sub() { let value = if x == "じゅげむ じゅげむ ごこうのすりきれ かいじゃりすいぎょの すいぎょうまつ うんらいまつ ふうらいまつ くうねるところにすむところ やぶらこうじのぶらこうじ ぱいぽ ぱいぽ ぱいぽのしゅーりんがん しゅーりんがんのぐーりんだい ぐーりんだいのぽんぽこぴーの ぽんぽこなーの ちょうきゅうめいのちょうすけ" { true } else { false }; }
識別子の並び替え方法の改善
Rust 2024では、生識別子を含む並び替え、数字を含む識別子の並び替えが、より自然になるように改良されました。
Rust Style Guideでは並び替えのルールも定めており、これはたとえばuse文による名前空間のインポートにも適用されます。従来は、以下のリストのような生識別子を含むuse文は、正しい並び替えが実施されませんでした。これは、r#asyncが先頭のr#を含めて認識されるためで、これでは生識別子を含むものだけ1箇所にまとめられてしまいます。
use websocket::header::Accept; use websocket::r#async::TcpListener; 本当はasyncとして先頭に出したい use websocket::stream::ReadWritePair;
Rust 2024では、以下のリストのようにr#を除いた部分で辞書順に並び替えられます。
use websocket::r#async::TcpListener; asyncが先頭に来る use websocket::header::Accept; use websocket::stream::ReadWritePair;
識別子そのものの比較にも新しいルールが適用されるようになりました。
従来は、ASCIIbetical(単純にASCIIコードに基づいた比較)に基づきましたが、Rust 2024ではUnicodeベースでバージョンソート(数字の大小や区切り文字なども考慮した並び替え)の並び替えが行われるようになりました。
たとえば以下のリストのように、順番を考慮していないuse文があるとします。
use std::num::{NonZeroI32, NonZeroI128, NonZeroI16, NonZeroI64, NonZeroI8}; use std::fs::{Permissions, File, hard_link, self};
従来は、以下のリストのように成形されていました。
use std::fs::{self, hard_link, File, Permissions}; use std::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8};
メソッド名などに使うsnake_caseが前に来てしまいます(selfとsuperは他の項目に関係なく最初に来ます)。また数字を含む場合、それが数値を表すものでも単純に辞書順となり、数値としての大小は無視されます。
これが、Rust 2024では以下のリストのように成形されます。
use std::fs::{self, File, Permissions, hard_link}; use std::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128};
構造体名などに使うUpperCamelCaseが前に来るようになり、数値の大小順に並ぶようになりました。
まとめ
今回は、RustのツールチェインであるパッケージマネージャCargoやコードフォーマッタRustFmtの変更について、Cargoのパッケージ管理機能とRustFmtのコードフォーマット機能のあらましとともに紹介しました。
次回は、マクロ機能に関する変更点として、フラグメント識別子の改善を中心にマクロ機能のあらましとともに紹介します。