Rustにおけるファイル分割

Sep 17 2018

Rustは、モジュールシステムも色々決まりがあって整っているので、単にファイルを分けて書こうと思った場合にも、整った綺麗な書き方をするには難しい言語に感じます。自分も、丁度Rustでプログラムを書いていた時に迷って良いリポジトリから良い書き方を見つけたのでその紹介をしようと思います

Rustは、モジュールシステムも色々決まりがあって整っているので、単にファイルを分けて書こうと思った場合にも、整った綺麗な書き方をするには難しい言語に感じます。

自分も、丁度Rustでプログラムを書いていた時に迷って良いリポジトリから良い書き方を見つけたのでその紹介をしようと思います。

情報が少ない!

Rustのファイル分割は、情報を探そうとしても自分はなかなか出てきませんでした。英語で検索かけても、まとまったページがなかったのでここにまとめておきます。

参考にしたリポジトリ

GitHub - maekawatoshiki/naglfar: A toy web browser implemented in Rust from scratch

これですね、Rustで色々書いてる人のリポジトリを参考にしました。

せっかちな人向けに最初に方法を

Rustはcargo testではlib.rsが実行され、cargo runmain.rsが実行されるようです。

main.rsには

/* main.rs */

extern crate クレート名;

fn main() {
    /* process ... */
}

こんな風に書きます。

そして、lib.rsには

/* lib.rs */

/* A */
pub mod structs;
pub mod token;
pub mod monominal;
pub mod expression;

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

ここでコード内Aの場所でpub modしてますが、pub modで指定したモジュール名に.rcをつけたファイルが自動的に読み込まれます。

なので、この上の例ではディレクトリ構造は以下のようになっているはずです。

. (クレート名)
├── Cargo.lock
├── Cargo.toml
└── src
    ├── main.rs
    ├── lib.rs
    ├── structs.rs
    ├── token.rs
    ├── monominal.rs
    └── expression.rs

/* token.rs */

use structs::*;

/* ... */

lib.rsにpub modされているファイルの1つ(token.rs)を見てみましょう。ここではstructs.rsの内容が必要なようです。このようなときにはuseを使いましょう。

まとめると、

Rustでファイル分割
1. main.rsでは(クレートを使うときは)extern crate クレート名を書いてモジュールを読み込める(必須ではない
2. lib.rsではpub mod モジュール名を使って公開するモジュールを指定する(公開したくなかったらpub抜いて)
3. モジュール名.rs内で他のモジュールを使いたい場合はuse モジュール名でどうぞ

内部の仕組みとか交えつつ説明

Rustのモジュールは色々管理されていて、他の言語から来た人には窮屈に感じることが在るかもしれません。

extern crate

これを使えば外部のクレートをインポートすることができます。

[pub] mod

これはモジュールを宣言することができます。他のファイル(モジュール名.rsモジュール名/mod.rs)を探しに行って読み込むことができます。pubを使うとそのモジュールを公開します。

例えばlib.rsにpubを付けないとmain.rsなど、そのクレートを使うスクリプトからextern crateで読み込んだ時に、内部のそのモジュールにアクセスできなくなります。

use

名前を短くするのに使うことができます。例えば、main.rsで

/* main.rs */

extern crate kokmath;
kokmath::structs::Token::Scalar(3.);
と書かないといけないところを簡単に
/* main.rs */

extern crate kokmath;
use kokmath::structs; // kokmath::structsをstructsと書くだけで良い
structs::Token::Scalar(3.);
と書いたり、
/* main.rs */

extern crate kokmath;
use kokmath::structs::*; // kokmath::structs::何か を 何か と書くだけで良い
Token::Scalar(3.);
と書いたりすることが出来るわけです。

pub use

これはちょっと複雑ですが、簡単に言うと構造を変えることができます。例えば、さっきのmain.rsでkokmath::structs::TokenとやってTokenにアクセスしていましたが、これはuseでどうやっても、kokmath::Tokenとやってアクセスするように変更することはできません

lib.rsを見れば分かるようにTokenはstructsの中にあって、それはpub mod structsで読み込まれていますので、これを実現するためにはkokmathのコードを改変する必要があります。なんとか、lib.rsでなんとかできないのか。こんな時にこれが使えて、

/* lib.rs */

pub mod structs;
pub mod token;
pub mod monominal;
pub mod expression;

pub use structs::*; // ここ! ここでstructsの中身を全て引き出して、「その結果を公開してこれを読み込むクレートに適用させる」

...
と書き換えることで、main.rsで
/* main.rs */

extern crate kokmath;
kokmath::Token::Scalar(3.);
とすることができます😊

まとめ

Rustでファイル分割
1. main.rsでは(クレートを使うときは)extern crate クレート名を書いてモジュールを読み込める(必須ではない
2. lib.rsではpub mod モジュール名を使って公開するモジュールを指定する(公開したくなかったらpub抜いて)
3. モジュール名.rs内で他のモジュールを使いたい場合はuse モジュール名でどうぞ

Read more?

超置換単語を楽に見つけたい ><!

Feb 12 2019

超置換単語(造語)というとても面白いものを†計算機の力†を使って探し出してみます

3次方程式の判別式

黄茶の問題を解いていると判別式をよく使います。3次方程式に対しても使いたい場面がちょっとあったので、考えます。

Jan 19 2019

あけましておめでとうございます

アケオメ

Jan 07 2019

数学 I(三角法) を勉強していく上で思ったこととかメモ

Oct 11 2018

黄茶の旅日記の様なものです。数Iの三角法です。

画面指紋認証の仕組みって

Jun 11 2018

最近、画面指紋認証の記事を見かけまして、「そういやこれどうやって出来てるのかな...」と思って記事探してみてもなかったので(英語でも少なかった)、幾つかのページ(参考文献)から引っ張り出してきた情報を元に記事を書きます

042933964230の暗号について調べてみた

Apr 23 2018

謎のサイトと言われて少し前に話題になったやつを調べてみました

日本一早いサイト選手権

阿部寛のホームページが爆速なのでそれよりはやいページ無いかなぁと適当に探してみた結果です。

Sep 22 2018

[円柱の体積文字列] 英単語をgrepできるサイトを作りました

Sep 17 2018

円の体積文字列で別の例を探すために英単語をgrep出来るサイトを作りました

数学 I(二次関数) を勉強していく上で思ったこととかメモ

黄茶の二次関数が終わったので、その学習中に思ったことを適当にメモしておきます

Sep 16 2018

IEは最高のブラウザ / IE is the best browser

Sep 16 2018

世間では何故かIEが蔑まれているようですが、そんなブラウザにも素晴らしいところが沢山あるのです

線の長さを積分で考えてみる

Sep 11 2018

今回は、前回積分を使って面積(小さな面積の集合)を求めたので、今回は線(小さな線の集合)の長さを求めていければ良いなぁみたいな感じでやっていけたらと思っています。

積分で原始関数の差を求めると元の函数の面積が出る理由

今回は積分の面白い性質である、原始関数の差が元の函数の面積となるという性質についてそうなる理由を気持ちだけでも書いていきます。

Sep 04 2018

「国語に関する世論調査」を読んで思ったこととか

Aug 28 2018

国の日本語に関する調査を見て最近の日本語の変化について知りました。

新しいブログシステムを構築したのでやったことを記録

前の古臭いブログシステムのままだと嫌だったので、新しいブログシステムを構築しました。

Aug 22 2018

共用サーバーで非同期通信チャットアプリを作る

今日は、さくらサーバーのライトプランという制限が多いサーバーでなんとか非同期通信を実現すべく奮闘したので、その記録をしたいと思います。

Aug 21 2018

前にブログに追加した機能

前にブログに追加した機能が使えるかどうかのテスト用.

Aug 21 2018

[素因数分解] Trial Division / 試し割り法

試し割り法は素因数分解の一番愚直なアルゴリズムです。この解説をします。

Aug 19 2018