26

次のコードがあります。

pub mod a {
    #[test]
    pub fn test() {
        println!("{:?}", std::fs::remove_file("Somefilehere"));
    }
}

これをコンパイルするとエラーが発生します。

error[E0433]: failed to resolve. Use of undeclared type or module `std`
 --> src/main.rs:4:24
  |
4 |         println!("{}", std::fs::remove_file("Somefilehere"));
  |                        ^^^ Use of undeclared type or module `std`

ただし、内部モジュールを削除して、それ自体に含まれるコードをコンパイルすると問題なく動作します。

#[test]
pub fn test() {
    println!("{:?}", std::fs::remove_file("Somefilehere"));
}

ここで何が欠けていますか?モジュールが別のファイルにある場合、同じエラーが発生します。

main.rs

pub mod a;

a.rs

#[test]
pub fn test() {
    println!("{:?}", std::fs::remove_file("Somefilehere"));
}
4

2 に答える 2

49

デフォルトでは、コンパイラextern crate std;は crate ルートの先頭に挿入します (crate ルートは に渡すファイルですrustc)。このステートメントは、名前stdをクレートのルート名前空間に追加し、クレートのパブリック コンテンツを含むモジュールに関連付ける効果がありますstd

ただし、子モジュールでstdは、モジュールの名前空間に自動的に追加されません。これが、コンパイラがモジュールstd(または で始まるもの) を解決できない理由です。std::

これを修正するには多くの方法があります。まず、モジュールを追加して、そのモジュール内でルートを参照use std;する名前を作成できます。ステートメントでは、パスは絶対 (または「クレートのルート名前空間に対する相対」) として扱われますが、それ以外の場所では、パスは現在の名前空間 (モジュール、関数など) に対する相対として扱われることに注意してください。stdstduse

pub mod a {
    use std;

    #[test]
    pub fn test() {
        println!("{:?}", std::fs::remove_file("Somefilehere"));
    }
}

ステートメントを使用して、useより具体的なアイテムをインポートすることもできます。たとえば、次のように書くことができますuse std::fs::remove_file;。これにより、パス全体を入力する必要がなくなり、そのモジュール内で直接remove_file名前を使用することができます。remove_file

pub mod a {
    use std::fs::remove_file;

    #[test]
    pub fn test() {
        println!("{:?}", remove_file("Somefilehere")));
    }
}

最後に、パスの前に を付けてコンパイラにクレートのルート名前空間からのパスを解決するように依頼する (つまり、パスを絶対パスに変換する)useことで、完全に使用を避けることができます。::

pub mod a {
    #[test]
    pub fn test() {
        println!("{:?}", ::std::fs::remove_file("Somefilehere"));
    }
}

推奨される方法は、タイプ (構造体、列挙型など) を直接インポートすること (たとえばuse std::rc::Rc;、次に pathRcを使用) ですが、親モジュールのインポートを通じて関数を使用すること (たとえばuse std::io::fs;、次に path を使用fs::remove_file) です。

pub mod a {
    use std::fs;

    #[test]
    pub fn test() {
        println!("{:?}", fs::remove_file("Somefilehere"));
    }
}

補足:パスの先頭に書き込んself::で、現在のモジュールを基準にすることもできます。他のパスはすでに相対であるため、これはステートメントでより頻繁に使用されuseます (ただし、それらは現在の名前空間に対してself::相対的ですが、常に含まれているモジュールに対して相対的です)。

于 2014-05-02T18:57:35.677 に答える