同じプロジェクトの別のファイルのモジュールを含める方法は?


130

このガイドに従って、Cargoプロジェクトを作成しました。

src/main.rs

fn main() {
    hello::print_hello();
}

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}

私が使っている

cargo build && cargo run

エラーなしでコンパイルされます。現在、メインモジュールを2つに分割しようとしていますが、別のファイルからモジュールを含める方法がわかりません。

私のプロジェクトツリーはこのように見えます

├── src
    ├── hello.rs
    └── main.rs

およびファイルの内容:

src/main.rs

use hello;

fn main() {
    hello::print_hello();
}

src/hello.rs

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}

私はそれをコンパイルするとcargo build、私が取得します

error[E0432]: unresolved import `hello`
 --> src/main.rs:1:5
  |
1 | use hello;
  |     ^^^^^ no `hello` external crate

コンパイラーの提案に従って、以下のように変更main.rsしました。

#![feature(globs)]

extern crate hello;

use hello::*;

fn main() {
    hello::print_hello();
}

しかし、これはまだあまり役に立ちません、今私はこれを手に入れました:

error[E0463]: can't find crate for `hello`
 --> src/main.rs:3:1
  |
3 | extern crate hello;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

現在のプロジェクトの1つのモジュールをプロジェクトのメインファイルに含める方法の簡単な例はありますか?



回答:


239

あなたは必要としないmod hello、あなたの中hello.rsのファイル。クレートルート以外のファイル内のコード(main.rs実行可能ファイルの場合lib.rs、ライブラリの場合)は、モジュールで自動的に名前空間が設定されます。

コードを含めるにはhello.rs、あなたの中にmain.rs、使用しますmod hello;。これは、含まれているコードに拡張さhello.rsれます(以前とまったく同じです)。ファイル構造は同じであり、コードを少し変更する必要があります。

main.rs

mod hello;

fn main() {
    hello::print_hello();
}

hello.rs

pub fn print_hello() {
    println!("Hello, world!");
}

1
Late Questionは、mod helloの代わりにuse helloで指定しても機能しませんか?
クリスチャンシュミット2015

16
@ChristianSchmittいいえ、違うものです。ファイルusemod取り込む一方で、名前空間のことです。useたとえば、print_hello名前空間を前に付けることなく関数を呼び出すことができるようにするために使用します
Renato Zannon

25

ネストされたモジュールが必要な場合...

錆2018

、もはや必要ないファイルを持っているmod.rs(それはまだサポートされていますが)。慣用的な代替案は、ファイルにモジュールの名前を付けることです:

$ tree src
src
├── main.rs
├── my
│   ├── inaccessible.rs
│   └── nested.rs
└── my.rs

main.rs

mod my;

fn main() {
    my::function();
}

my.rs

pub mod nested; // if you need to include other modules

pub fn function() {
    println!("called `my::function()`");
}

錆2015

mod.rsモジュールと同じ名前のファイルをフォルダー内に配置する必要があります。Rust by Exampleはそれをよりよく説明しています。

$ tree src
src
├── main.rs
└── my
    ├── inaccessible.rs
    ├── mod.rs
    └── nested.rs

main.rs

mod my;

fn main() {
    my::function();
}

mod.rs

pub mod nested; // if you need to include other modules

pub fn function() {
    println!("called `my::function()`");
}

4
から何かを使用したいとinaccessible.rsnested.rsます...それをどのように行うのですか?
Heman Gandhi

main.rs以外のファイルから兄弟.rsファイルにアクセスするには、path属性を使用します。そのため、nested.rsの先頭に次を追加します。 #[path = "inaccessible.rs"]次の行に:mod inaccessible;
Gardener


2
@HemanGandhi add mod inaccessible;to my/mod.rsをサブmyモジュールにしてからnested.rs、相対パスで兄弟モジュールにアクセスしますsuper::inaccessible::function()pathここでは属性は必要ありません。
artin

9

私は庭師の反応が本当に好きです。私は自分のモジュール宣言の提案を使用しています。これに技術的な問題がある場合は、誰かがチャイムを入れてください。

./src
├── main.rs
├── other_utils
│   └── other_thing.rs
└── utils
    └── thing.rs

main.rs

#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;

fn main() {
  thing::foo();
  other_thing::bar();
}

utils / thing.rs

pub fn foo() {
  println!("foo");
}

other_utils / other_thing.rs

#[path = "../utils/thing.rs"] mod thing;

pub fn bar() {
  println!("bar");
  thing::foo();
}

再輸出にこの「トリック」を使用する必要がありましたfn。それはにあったファイルと同じ名前を持つ#[path = "./add_offer.rs"] mod _add_offer; pub use self::_add_offer::add_offer;
Arekバル

これは、受け入れられる答えになるはずですimo
Homam Bahrani
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.