入れ子のモジュールをフルパスで呼ぶ書き方と、use で短くした書き方を並べた最小の例です。use tools::text と書いておけば、以降は text::shout だけで呼べます。動きは何も変わらず、呼び出しが読みやすくなるだけ、というのが use の本質です。
Rust
mod tools {
pub mod text {
pub fn shout(word: &str) {
println!("{}!", word);
}
}
}
use tools::text;
fn main() {
tools::text::shout("フルパスで呼ぶ");
text::shout("use で短くして呼ぶ");
}
2構造体は型自体を use する
関数は親モジュールまでを use するのに対し、構造体や enum は型自体を use するのが慣習であることを示す例です。use models::Book としておけば、main では Book という短い名前だけで構築できます。この慣習を守ると「どこから来た名前か」がコードベース全体で予測しやすくなります。
Rust
mod models {
pub struct Book {
pub title: String,
pub pages: u32,
}
}
use models::Book; // 型は型自体を use するのが慣習
fn main() {
let book = Book { title: String::from("Rust入門"), pages: 300 };
println!("{} ({}ページ)", book.title, book.pages);
}
3標準ライブラリを use する
自作モジュールだけでなく、標準ライブラリも std の下のモジュールを use して使うことを示す例です。関数は親モジュールまで取り込む慣習どおり、use std::cmp として cmp::max の形で呼んでいます。std::collections や std::num など、実務ではこの形の use がファイル冒頭に並びます。
Rust
use std::cmp; // 標準ライブラリのモジュールを取り込む
fn main() {
let a = 30;
let b = 17;
println!("大きい方 = {}", cmp::max(a, b));
println!("小さい方 = {}", cmp::min(a, b));
}
4as で別名を付けて衝突を避ける
2つのモジュールが同名の関数を持つとき、use パス as 別名 で名前を付け替えて両方取り込む例です。そのまま use すると名前が衝突しますが、別名なら呼び出し側で取り違える心配もありません。外部ライブラリどうしで型名が被ったときにも、実務でそのまま使えるテクニックです。
Rust
mod tax_jp {
pub fn with_tax(price: u32) -> u32 {
price * 110 / 100
}
}
mod tax_us {
pub fn with_tax(price: u32) -> u32 {
price * 105 / 100
}
}
use tax_jp::with_tax as with_tax_jp; // as で別名を付けて衝突を回避
use tax_us::with_tax as with_tax_us;
fn main() {
println!("日本の税込: {}", with_tax_jp(1000));
println!("米国の税込: {}", with_tax_us(1000));
}
5深い階層のモジュールを use で整える
services::billing::invoice という3階層のパスを、use で invoice まで縮めて使う実務寄りの例です。請求関連の処理を何度も呼ぶコードでは、毎回フルパスを書くと本質的なロジックが埋もれてしまいます。「ファイル冒頭の use を見れば依存先が一覧できる」状態を保つのが読みやすいコードの定石です。
Rust
mod services {
pub mod billing {
pub mod invoice {
pub fn total(unit: u32, qty: u32) -> u32 {
unit * qty
}
pub fn with_fee(amount: u32) -> u32 {
amount + 200
}
}
}
}
use services::billing::invoice;
fn main() {
let amount = invoice::total(1200, 3); // フルパスを書かずに済む
println!("請求額 = {} 円", invoice::with_fee(amount));
}