###### tags: `Rust` `crate` `module `use` `extern crate` # Rust テキスト学習 7 # クレートとモジュール - crate : ライブラリ、パッケージ - module : ローカルインポートするモジュール main() を持たないファイルはライブラリとしてビルドされる 拡張子は .rlib (rust library) ## クレートのフォルダ構造 `cargo new <ライブラリ名> --lib` --lib オプションを付けて cargo new コマンドを実行すると、 ライブラリプロジェクト(クレート)を作成することができる。 ### lib.rs ライブラリのルートであることが期待されるファイル。 クレートのルート。 --bin (もしくはなし) : エントリーポイントが main.rs --lib : ルートが lib.rs ## モジュール定義 mod mod キーワード でモジュールを定義する mod内ではサブmodが使える ```rust= mod english{ mod greetings { } mod farewells { } } mod japanese { mod greetings { } mod farewells { } } ``` 2重コロン記法で下位のモジュールにアクセスできる mod内は区切られたnamespaceとなり、 fn や struct が定義できる。 ## 複数ファイルのクレート ルートのlib.rsにすべてのモジュールを記述する代わりに、 ファイルを分割してmoduleを記述できる。 その場合、ルートには mod モジュール名; を記述し、 ブロックの中身だけ別ファイルに書く lib.rs ```rust= mod english; mod japanese; ``` english.rs ```rust= mod greetings; mod farewells; ``` 上記のように書いた場合、Rustコンパイラは - ./english.rs - ./english/mod.rs のどちらかにenglish modがあることを予想する。 その中でmod キーワードを再度宣言する必要はない。 (サブモジュール以下も同様) # 外部クレートの使用 クレートを使用できるようにするには - export - import の両方が必要 ## export クレート外から使いたいmodの宣言に pub属性をつけるだけ ```rust= // lib.rs pub mod english; pub mod japanese; // english.rs pub mod greetings; pub mod farewells; // farewells.rs pub fn goodbye () { println!("goodbye"); } pub struct Person { pub name: String, pub age : i32, } ``` 注意する点として、 **Rustでは全てがデフォルトでprivate** mod, fn, struct 定義全てにpubを書く必要がある structに関してはメンバもすべてpubをつける。 ## import importするためのキーワードは2種類 - extern crate - use ### extern crate extern crate = コンパイルしてクレートをリンクせよという指示 `extern crate \<crate名>;` クレートのrootをインポートする。 extern = 外部の lib.rs と main.rs は別々のクレートと考えられている たとえ --bin コマンドで作成したプロジェクトでも、 処理の殆どを lib.rs におき、 main.rs からは呼び出すだけ というふうにすると、関心の分離ができて素敵。 ### use `use <crate名>::mod1::submod1::{fn1, struct1, ...}` クレートはモジュール単位でインポートするのがおすすめとされている。 以下のような場合は、hello() という名前の関数が2つインポートされてエラーになる。 名前がかぶらない地点までをインポートしよう。 ```rust= extern crate phrases; use phrases::english::greetings::hello; use phrases::japanese::greetings::hello; fn main() { println!("Hello in English: {}", hello()); println!("Hello in Japanese: {}", hello()); } ``` # pub use exportの再定義 モジュールが自分のルートからの相対的なモジュールをスコープに取り込み、 pubを使うことで異なるモジュール階層からimportできるようにする。 ```rust= pub use self::greetings::hello; pub use self::farewells::goodbye; mod greetings; mod farewells; ``` self = 現在のmodule(上の例ではjapaneseモジュール) # import オプション - * : すべてのモジュールをインポート - as Alias : 別名でインポート - {} : 複数のimport文を圧縮 ```rust= extern crate phrases as sayings; use sayings::japanese::greetings as ja_greetings; use sayings::japanese::farewells::*; use sayings::english::{self, greetings as en_greetings, farewells as en_farewells}; ```