🦀
Rustの勉強 7日目
The Rust Programming Language 日本語版 第7章
7.1 パッケージとクレート
- クレートにはバイナリとライブラリの2種類がある
- パッケージは
Cargo.toml
でビルド方法に関する情報を保持 -
cargo new
で新規パッケージを作成-
src/main.rs
はパッケージ名と同名のバイナリクレートのルート -
src/lib.rs
はパッケージ名と同名のライブラリクレートのルート
-
7.2 モジュールを定義して、スコープとプライバシーを制御する
- ライブラリパッケージを作る場合
cargo new --lib
で出来る - モジュールはクレート内のコードをグループ化する。プライバシーの制御もする。
-
mod
キーワードでモジュールのスコープを作成する- モジュールはネストできる
- モジュールはツリー構造で管理される
- 一番の親は必ず
crate
というクレートとなる
- 一番の親は必ず
7.3 モジュールツリーの要素を示すためのパス
- モジュールパスは相対パスでも絶対パスでも
::
の区切りで表す- 絶対と相対の表し方はファイルパスと似ている
- 親モジュールの相対パスは
super
で始めればよい(ファイルパスで言うところの..
)
- あらゆる要素はデフォルトではプライベート
- 親は子モジュールの要素は原則プライベートで使えない
- 子は親モジュールの要素を使える
-
pub
キーワードを使うことで外部に公開できる- モジュール名に
pub
を付けても中身が公開されるわけではない - 公開する要素ごとに
pub
を付けないといけない - 公開する要素というのは各構造体のフィールドも含む(Goでもフィールドごとに大文字・小文字で公開非公開を分けているので同様)
- Enum型の場合は
enum
キーワードの前にpub
を置くだけで全列挙子が公開される(されないと困るので直感的)
- モジュール名に
7.4 useキーワードでパスをスコープに持ち込む
-
use
キーワードを使うといちいち相対パスや絶対パスでモジュールを使わなくて済む - 関数を呼ぶ場合は慣例では公開されているモジュールを
use
して、モジュール名::関数名
で呼ぶ- 直接関数を
use
してしまうと分かりづらい
- 直接関数を
- データ型を呼ぶ場合はフルパスを
use
で指定する- データ型にはメソッドなどがあるのでモジュールまでとすると記述量が長くなってしまう
- 同じ名前の型を同じモジュールで使う場合には親モジュール名を指定しなければいけない
-
as
キーワードを使うとエイリアスを与えることが出来、これで名前の衝突を避けられる
-
use std::fmt;
use std::io;
fn function1() -> fmt::Result { ... }
fn function2() -> io::Result { ... }
-
pub use
を使うと、自分たちがuse
したモジュールをそのままの形で公開できる - 同じ親を持つ複数のモジュールを波カッコで囲ってまとめて
use
できる - また glob を使ってまとめて取り込むことも出来る
use std::{cmp::Ordering, io};
use std::io::{self, Write};
use std::collections::*;
7.5 モジュールを複数のファイルに分割する
- ブロックを作らずに
mod モジュール名;
という文を書くと、モジュール名と同名のファイルやディレクトリから中身を引っ張ってくる
Rustlings
modules が第7章に相当するのでやってみる
modules1.rs
sausage_factory
モジュール自体とその中の make_sausage
関数はプライベートなので、pub
を使って公開する
pub mod sausage_factory {
// Don't let anybody outside of this module see this!
fn get_secret_recipe() -> String {
String::from("Ginger")
}
pub fn make_sausage() {
get_secret_recipe();
println!("sausage!");
}
}
fn main() {
sausage_factory::make_sausage();
}
modules2.rs
fruits
と veggies
の中の const
の宣言方法はよくわからないけど、 println!
の中で参照されているものが存在しないので、エイリアスとして定義した。
pub mod delicious_snacks {
pub use self::fruits::PEAR as fruit;
pub use self::veggies::CUCUMBER as veggie;
mod fruits {
pub const PEAR: &'static str = "Pear";
pub const APPLE: &'static str = "Apple";
}
mod veggies {
pub const CUCUMBER: &'static str = "Cucumber";
pub const CARROT: &'static str = "Carrot";
}
}
fn main() {
println!(
"favorite snacks: {} and {}",
delicious_snacks::fruit,
delicious_snacks::veggie
);
}
modules3.rs
問題のコメントに std::time
モジュールにあるよ、って書いてあったので、まとめて use
した。
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
}
}
Discussion