為了解決不同開發者有各自不同的程式碼風格的問題。像是有些人習慣用一個tab字元進行縮排;有些人則習慣用兩個或四個空格字元來進行縮排。有些人習慣if或for迴圈的大括號要先換行;有些人則習慣和關鍵字寫在同一行。Rust官方提供了rustfmt這個工具來進行官方建議的程式排版方式。



使用rustfmt

rustfmt指令可以針對特定幾個Rust檔案(.rs)進行排版。例如:

rustfmt src/lib.rs src/main.rs

如果是要排版整個Cargo專案下的Rust檔案,指令如下:

cargo fmt

排版風格

rustfmt的排版風格是可以自訂的。rustfmt或是cargo fmt指令在執行的時候,首先會尋找工作目錄中是否有.rustfmt.toml檔案,如果有的話就會將其作為rustfmt的設定檔,如果沒有的話就會再尋找工作目錄中是否有rustfmt.toml檔案,如果還是沒有的話,就會去尋找上層目錄是否有.rustfmt.tomlrustfmt.toml檔案,依此類推。至於rustfmt設定檔的撰寫方式,可以參考這個文件

以下是一個rustfmt設定檔的撰寫範例:

brace_style = "PreferSameLine"
enum_discrim_align_threshold = 100
force_explicit_abi = false
force_multiline_blocks = true
format_code_in_doc_comments = true
format_macro_matchers = true
max_width = 100
newline_style = "Unix"
normalize_doc_attributes = true
overflow_delimited_expr = true
reorder_impl_items = true
struct_lit_single_line = false
use_field_init_shorthand = true
use_small_heuristics = "Off"
use_try_shorthand = true

rustfmt的設定檔有些設定項目是不穩定的(unstable),如果要將其加進rustfmt設定檔中並成功套用的話,要使用Rust Nightly版本的rustfmt。可以用以下指令來安裝Rust Nightly:

rustup toolchain add nightly

並用以下指令來排版整個Cargo專案:

cargo +nightly fmt

利用巨集來略過排版

如果我們某部份的程式碼想要保留輸入時的排版方式,可以對其添加#[rustfmt::skip]屬性。

例如:

#[rustfmt::skip]
const NO_REF_8_07: [u8; 256] = [0u8, 7u8, 14u8, 9u8, 28u8, 27u8, 18u8, 21u8, 56u8, 63u8, 54u8, 49u8, 36u8, 35u8, 42u8, 45u8, 112u8, 119u8, 126u8, 121u8, 108u8, 107u8, 98u8, 101u8, 72u8, 79u8, 70u8, 65u8, 84u8, 83u8, 90u8, 93u8, 224u8, 231u8, 238u8, 233u8, 252u8, 251u8, 242u8, 245u8, 216u8, 223u8, 214u8, 209u8, 196u8, 195u8, 202u8, 205u8, 144u8, 151u8, 158u8, 153u8, 140u8, 139u8, 130u8, 133u8, 168u8, 175u8, 166u8, 161u8, 180u8, 179u8, 186u8, 189u8, 199u8, 192u8, 201u8, 206u8, 219u8, 220u8, 213u8, 210u8, 255u8, 248u8, 241u8, 246u8, 227u8, 228u8, 237u8, 234u8, 183u8, 176u8, 185u8, 190u8, 171u8, 172u8, 165u8, 162u8, 143u8, 136u8, 129u8, 134u8, 147u8, 148u8, 157u8, 154u8, 39u8, 32u8, 41u8, 46u8, 59u8, 60u8, 53u8, 50u8, 31u8, 24u8, 17u8, 22u8, 3u8, 4u8, 13u8, 10u8, 87u8, 80u8, 89u8, 94u8, 75u8, 76u8, 69u8, 66u8, 111u8, 104u8, 97u8, 102u8, 115u8, 116u8, 125u8, 122u8, 137u8, 142u8, 135u8, 128u8, 149u8, 146u8, 155u8, 156u8, 177u8, 182u8, 191u8, 184u8, 173u8, 170u8, 163u8, 164u8, 249u8, 254u8, 247u8, 240u8, 229u8, 226u8, 235u8, 236u8, 193u8, 198u8, 207u8, 200u8, 221u8, 218u8, 211u8, 212u8, 105u8, 110u8, 103u8, 96u8, 117u8, 114u8, 123u8, 124u8, 81u8, 86u8, 95u8, 88u8, 77u8, 74u8, 67u8, 68u8, 25u8, 30u8, 23u8, 16u8, 5u8, 2u8, 11u8, 12u8, 33u8, 38u8, 47u8, 40u8, 61u8, 58u8, 51u8, 52u8, 78u8, 73u8, 64u8, 71u8, 82u8, 85u8, 92u8, 91u8, 118u8, 113u8, 120u8, 127u8, 106u8, 109u8, 100u8, 99u8, 62u8, 57u8, 48u8, 55u8, 34u8, 37u8, 44u8, 43u8, 6u8, 1u8, 8u8, 15u8, 26u8, 29u8, 20u8, 19u8, 174u8, 169u8, 160u8, 167u8, 178u8, 181u8, 188u8, 187u8, 150u8, 145u8, 152u8, 159u8, 138u8, 141u8, 132u8, 131u8, 222u8, 217u8, 208u8, 215u8, 194u8, 197u8, 204u8, 203u8, 230u8, 225u8, 232u8, 239u8, 250u8, 253u8, 244u8, 243u8];

#[rustfmt::skip]
const NO_REF_8_1D: [u8; 256] = [0u8, 29u8, 58u8, 39u8, 116u8, 105u8, 78u8, 83u8, 232u8, 245u8, 210u8, 207u8, 156u8, 129u8, 166u8, 187u8, 205u8, 208u8, 247u8, 234u8, 185u8, 164u8, 131u8, 158u8, 37u8, 56u8, 31u8, 2u8, 81u8, 76u8, 107u8, 118u8, 135u8, 154u8, 189u8, 160u8, 243u8, 238u8, 201u8, 212u8, 111u8, 114u8, 85u8, 72u8, 27u8, 6u8, 33u8, 60u8, 74u8, 87u8, 112u8, 109u8, 62u8, 35u8, 4u8, 25u8, 162u8, 191u8, 152u8, 133u8, 214u8, 203u8, 236u8, 241u8, 19u8, 14u8, 41u8, 52u8, 103u8, 122u8, 93u8, 64u8, 251u8, 230u8, 193u8, 220u8, 143u8, 146u8, 181u8, 168u8, 222u8, 195u8, 228u8, 249u8, 170u8, 183u8, 144u8, 141u8, 54u8, 43u8, 12u8, 17u8, 66u8, 95u8, 120u8, 101u8, 148u8, 137u8, 174u8, 179u8, 224u8, 253u8, 218u8, 199u8, 124u8, 97u8, 70u8, 91u8, 8u8, 21u8, 50u8, 47u8, 89u8, 68u8, 99u8, 126u8, 45u8, 48u8, 23u8, 10u8, 177u8, 172u8, 139u8, 150u8, 197u8, 216u8, 255u8, 226u8, 38u8, 59u8, 28u8, 1u8, 82u8, 79u8, 104u8, 117u8, 206u8, 211u8, 244u8, 233u8, 186u8, 167u8, 128u8, 157u8, 235u8, 246u8, 209u8, 204u8, 159u8, 130u8, 165u8, 184u8, 3u8, 30u8, 57u8, 36u8, 119u8, 106u8, 77u8, 80u8, 161u8, 188u8, 155u8, 134u8, 213u8, 200u8, 239u8, 242u8, 73u8, 84u8, 115u8, 110u8, 61u8, 32u8, 7u8, 26u8, 108u8, 113u8, 86u8, 75u8, 24u8, 5u8, 34u8, 63u8, 132u8, 153u8, 190u8, 163u8, 240u8, 237u8, 202u8, 215u8, 53u8, 40u8, 15u8, 18u8, 65u8, 92u8, 123u8, 102u8, 221u8, 192u8, 231u8, 250u8, 169u8, 180u8, 147u8, 142u8, 248u8, 229u8, 194u8, 223u8, 140u8, 145u8, 182u8, 171u8, 16u8, 13u8, 42u8, 55u8, 100u8, 121u8, 94u8, 67u8, 178u8, 175u8, 136u8, 149u8, 198u8, 219u8, 252u8, 225u8, 90u8, 71u8, 96u8, 125u8, 46u8, 51u8, 20u8, 9u8, 127u8, 98u8, 69u8, 88u8, 11u8, 22u8, 49u8, 44u8, 151u8, 138u8, 173u8, 176u8, 227u8, 254u8, 217u8, 196u8];

以上兩個陣列因為很長,而且也沒有排版的意義,所以就直接讓它從頭到尾一行寫完,並且加上#[rustfmt::skip]屬性,使它們不會被rustfmt排版。

單純檢查沒有排好的地方

rustfmtcargo fmt指令預設會直接對原檔案進行排版更動,如果我們只是想要檢查Rust檔案中有哪些地方沒有按照rustfmt設定檔的規則來排版的話,可以加上--check參數。

如下:

rustfmt --check src/main.rs
cargo fmt -- --check