---
# System prepended metadata

title: Rust テキスト学習 7
tags: [crate, Rust, ' ', 'module ']

---

###### 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};
```