はじめに
これまでの記事ではmain.rsに全てのコードを書いてきました。しかし、実際にはファイルを分割してコードの見通しを良くしたくなると思います。そういった場合に必要となる、Rustのモジュールについて今回調べました。
Rustのモジュール
それでは、前回作ったコードを分割していき、次のような構造にしたいと思います。
- model/
- enums.rs
- message.rs
- main.rs
- model.rs
Rustではファイル分割していくと、そのファイル単位がモジュールとなります。上記の構造の場合、modelモジュールがあり、そのサブモジュールとしてさらにenumsとmessagesがあるという状態です。
それでは、1つずつ見ていきます。
モジュールツリーの構築
Rustはビルド時にルートモジュールを起点にビルドされます。デフォルトではmain.rsとlib.rsがルートとなっています。(今回はmain.rsをルートとした例を取り上げます。)
main.rsとlib.rs以外に作成したモジュールは、
mod
キーワードを使ってモジュールを宣言し、そのモジュール名と同名のRustファイルを読み込ませる必要があります。
例えば、今回の例ではmain.rsに次のように宣言します。
1 | mod model; |
こうすることで、model.rsがビルド対象に組み込まれました。
サブモジュール
今回の例では、models.rsとmodelsディレクトリの両方があり、modelsディレクトリには2つのRustファイルが入っていることに気が付きます。
これは、Rustでのサブモジュールの作り方となっていて、この作り方を説明します。
まず、models.rsは次のような内容となっています。
1 2 | pub mod enums; pub mod message; |
再び、modが出てきました。ここでは、モジュール名と同名のディレクトリ以下のサブモジュールを宣言しています。
models.rsは既にmain.rsでmod宣言されているため、このようにすることで末端までモジュールツリーが構成され、ビルド対象となります。
各モジュールの実装
一旦、ここで各モジュールの実装をしていきます。
まずは、enums.rsです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #[derive(Debug)] pub enum Content { Text(String), Photo { url: String, caption: String }, Video { url: String, length: i32 }, Deleted, } impl Content { pub fn print(&self) { match self { Content::Text(text) => println!("text: {}", text), Content::Photo { url, caption } => { println!("url: {}, caption: {}", url, caption) } Content::Video { url, length } => println!("url: {}, length: {}", url, length), Content::Deleted => println!("canceled"), } } } |
次に、messages.rsです。
1 2 3 4 5 6 7 | use super::enums::Content; #[derive(Debug)] pub struct Message { pub id: i32, pub content: Content, } |
最後に、main.rsです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | use model::{enums::Content, message::Message}; mod model; fn main() { // some_sample() let messages = [ Message { id: 1, content: Content::Text("Hello".to_string()), }, Message { id: 2, content: Content::Photo { url: "https://example.com/photo.jpg".to_string(), caption: "Hello".to_string(), }, }, Message { id: 3, content: Content::Video { url: "https://example.com/video.mp4".to_string(), length: 15, }, }, Message { id: 4, content: Content::Deleted, }, ]; for x in &messages { x.content.print(); } } |
モジュールのプライバシー
モジュールをpublicにするのか、privateにするのか制御するためには、pubキーワードを使います。pubキーワードを付加すると、同じディレクトリ階層に公開することができます。
例えば、Content Enumはpubが付いているので、modelディレクトリ配下で公開されています。そのため、message.rsで使用することができています。
また、model.rsでmodの宣言時にも
pub mod enums
のように、pubキーワードが使われています。このようにすることで、サブモジュールを1津上のディレクトリに公開することができます。
さいごに
今回はRustのモジュールについて調べた内容をまとめました。次回もRustを深掘りしていきたいと思います!