🦀
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