web-dev-qa-db-ja.com

「未解決のインポート-おそらくexternが欠落しています」extern宣言が存在する場合

すべてが1つの大きな.rsファイルに含まれていれば、問題なくビルドされた小さなプロジェクトがあります。作業を簡単にしたかったので、モジュールに分割しました。プロジェクトは次のように構成されています。

├── GameState
│   ├── ballstate.rs
│   ├── collidable.rs
│   ├── gamestate.rs
│   ├── mod.rs
│   └── playerstate.rs
├── lib.rs
└── main.rs

ballstate.rsでは、Randクレートを使用する必要があります。ファイルの短縮バージョンは次のとおりです。

extern crate Rand;

pub struct BallState {
    dir: Point,         
    frame: BoundingBox  
}                     

impl BallState {
    fn update_dir(&mut self) {
        use Rand::*;                                                                                                                                                                    
        let mut rng = Rand::thread_rng();                                                                      
        self.dir.x = if rng.gen() { Direction::Forwards.as_float() } else { Direction::Backwards.as_float()  };
        self.dir.y = if rng.gen()  { Direction::Forwards.as_float() } else { Direction::Backwards.as_float() };
    }                                                                                                        
}

ただし、最上位ディレクトリからcargo buildを実行すると、次のエラーが発生します。

GameState/ballstate.rs:42:9:42:13エラー:未解決のインポートRand::*。たぶんextern crate Randがありませんか?

Main.rsファイルにexterncrate宣言があったとき、これは機能しました。別のモジュールに含まれるようになった今、何が変更されましたか?

14
Ben Pious

Rust本 のクレートとモジュールの章から引用するには:

[...] use宣言は、クレートルートから始まる絶対パスです。 selfは、代わりに階層内の現在の場所を基準にしてそのパスを作成します。

コンパイラは正しいです。 Randのようなものはありません。モジュール内に配置しているため、正しいパスはGameState::ballstate::Rand、またはself::Randモジュール内からのGameState::ballstateになります。

extern crate Rand;をルートモジュールに移動するか、self::Randモジュール内でGameState::ballstateを使用する必要があります。

19
DK.

extern crate Rand;またはmain.rsファイルにlib.rs行を挿入する必要があります。他のファイルに入れる必要はありません。

おそらくそれは このバグ に関連しています。

2
antoyo