ヤルキデナイズド

Unclassified Articles on Software and IT

Rust 言語のモジュールシステム

追記:以下の記述は古くなっており、現在(バージョン0.12)のモジュールシステムとは異なる。

Rust 言語のモジュールシステム、なかなかイケてる。

概略

1ソースファイルが1モジュール(=1つの名前空間)になる。ライブラリや実行ファイルは1つ以上のモジュールからなり、クレート(crate)という単位にまとまる。クレートも1つの名前空間を構成する。クレートはバージョン番号や UUID によって一意に識別されるので、名前空間の衝突を回避できる。

クレートの使用

たとえば、 Rust の標準ライブラリである std クレートを使うには

use std;

fn main() {
   std::io::println("hello");
}

のように use 文でクレートの使用を宣言する。 std クレートは現在のスコープの std 名前空間にインポートされる。また、クレート名と異なる名前空間にインポートすることもできる。

use renamed_std (name = "std");

fn main() {
    renamed_std::io::println("hello");
}

クレートはバージョン番号や UUID などのメタデータを持ち、それらによって一意に識別できる。

use foo (ver = "1.0.0");
use old_foo (name = "foo", ver = "0.9.0");
use bar (uuid = "b35b2cf2-51c0-11e1-bcd3-a7d2c8974bdb");

fn main() {
    foo::do_something();
    old_foo::do_something();

    bar::blah();
}

名前空間

Rust の名前空間には3種類ある。上で述べた「名前空間」はモジュール名前空間のこと。他に型の名前空間と識別子の名前空間がある。下記の例では str モジュールと str 型と str 関数を混在させている。

use std;

mod str {
    fn str() -> str { "hello" }
}

fn main() {
    let str = str::str();
    std::io::println(str);
}

クレートファイル

複数のモジュールファイルからなるライブラリや実行ファイルを作るには、どのモジュールファイルを含むかを記述したクレートファイルが必要になる。

挨拶を出力する実行ファイル hello を作ることを考えてみよう。この実行ファイルは、 main 関数を持つモジュールファイル hello.rs と、 say_hello 関数を持つモジュールファイル greet.rs、そしてクレートファイル hello.rc からなるとする。モジュールファイルは下記のとおり:

// hello.rs

import greet;

fn main() {
    greet::say_hello();
}

// greet.rs

use std;

fn say_hello() {
    std::io::println("hello");
}

クレートファイル hello.rc の中では、実行ファイルに greet モジュールが含まれることを宣言する(hello モジュールはクレートと同名なので宣言不要):

// hello.rc

mod greet;

この実行ファイルをコンパイルするには rustc hello.rc とする。

Rust コンパイラ複数のソースファイルを入力することはできない。入力は常に1つのクレートファイルか1つのモジュールファイル(そのモジュールだけからなるクレートを作る場合に限る)である。