RustのModule
moduleの作り方は2つある
mod {..}を使う
code:main.rs
mod my_module {
pub fn greet() {
println!("Hello from my_module!");
}
}
fn main() {
my_module::greet();
}
ファイルに分割し、modでコンパイル対象に含める
code:my_module.rs
pub fn greet() {
println!("Hello from my_module!");
}
code:main.rs
mod my_module; // my_moduleをimport
fn main() {
my_module::greet();
}
structの各メンバは、同一module内からは、pub/pri関係なくアクセス可能
モジュールの宣言とファイルの読み込み
モジュール全体を定義し、コンパイル対象に含める
新しいモジュールを使用する際に必須
モジュール内の項目をスコープに持ち込む
名前の参照を簡略化するのみ
モジュール内の特定の項目を利用する際に任意
tsとの比較
tsユーザが理解しづらい点
rustでは、moduleの読み込みと、itemのスコープへの取り込みが別々に行われる
code:main.rs
mod hoge; // hoge.rs を読み込んでモジュールとして宣言
use hoge::greet; // hoge モジュール内の greet 関数をスコープに持ち込む
fn main() {
hoge::greet(); // use書かずにこれでもいい
greet(); // useしてれば直接呼び出せる
}
code:main.ts
import { greet } from './hoge';
greet();
tsの場合、自作のファイルも、外部ライブラリも、「module」という同等のものとして使用できる
pathの指定方法はちょっと異なるが、両方とも同じようにimportで読み込める
carteはコンパイル単位、moduleはcrateより細かい単位
自作のファイルはmodで宣言する必要し、必要であればuseで名前空間の省略ができる
外部ライブラリの場合、cargo.tomlに書いた時点で、すでにmod宣言がされているような状態になるので、わざわざmodなんちゃらと書かなくてもコンパイル対象になる(?)し、useするだけで読み込める
特別扱いされるファイル名
↓は2019年のときのメモなので全体的に理解が終わっている
module
関数、構造体、トレイト、implブロックなどの要素の集合のこと
moduleの中にmoduleも入る
プロジェクト内のコード構造化のための機構
main.rsとlib.rsという'ファイル名'は特別
使い方としては、lib.rsにライブラリをまとめて、main.rsで使う
main.rsで一つ、lib.rsを含んだそれ以外で一つ、と別々のクレート(木箱)に入っている感じ(?)
main.rsの中にはmain()という関数が必要
main.rsとlib.rsがある時、main.rsから見える別のファイルはlib.rsだけ?
見たければlib.rsの中の記述を
code:rs
pub mod module_a // main.rsからも見えるようにpubを付ける
importする側
moduleを読み込む時のmod
コンパイラはmod A;を見つけると
以下の両方をチェックする
A.rs
A/mod.rs
両方共ある、両方共ない場合、Errorになる
プロジェクト内のコードのどこからでも絶対パスで参照できる
絶対パス
::std::memのように::から始めると絶対パスを表す
この書き方は基本しない
use std::memのようにuseを使うと自動的に絶対パスになる
create::で始まるパスも絶対パス
code:rust
fn main() {
// モジュールによって、同名の関数を区別することができる。
my::function();
// パブリックな要素ならば、たとえネストしたものでも、
// モジュールの外からアクセスすることができる。
my::nested::function();
}
複数import
code:rs
use std::io::{stdin, BufRead, BufReader};
全import
code:rs
use std::io::prelude::*;
相対パス
superまたはselfを使う
use self::module_a
selfはディレクトリの.
現在のmodule
use super::module_a
superはディレクトリの..
superは親moduleのエイリアス
謎
以下の構成の時にエラーが出るのはなぜ?
わざわざディレクトリを分けないといけない?
code:tree
| Cargo.toml
|
\---src
| main.rs
| lexer.rs
| parser.rs
code:rs
// parser.
mod lexer; // help: name the file either parser/lexer.rs or parser/lexer/mod.rs inside the directory "src"
...
参考