在单独的模块中使用时,使用未声明的类型或模块`std`

luk*_*uke 18 rust

我有以下代码:

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

我编译时遇到错误:

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`
Run Code Online (Sandbox Code Playgroud)

但是,删除内部模块并编译它自己包含的代码可以正常工作:

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

我在这里错过了什么?如果模块位于单独的文件中,我会得到相同的错误:

main.rs

pub mod a;
Run Code Online (Sandbox Code Playgroud)

a.rs

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

Ren*_*non 39

默认情况下,编译器extern crate std;在crate根的开头插入(crate root是你传递给的文件rustc).此语句具有将名称添加std到包的根命名空间并将其与包含包的公共内容的模块相关联的效果std.

但是,在子模块中,std不会自动添加到模块的命名空间中.这就是编译器无法在模块中解析std(或以任何开头的方式std::)的原因.

有很多方法可以解决这个问题.首先,您可以添加use std;一个模块,使该模块中的名称std引用到根目录std.请注意,在use语句中,路径被视为绝对路径(或"相对于crate的根命名空间"),而在其他任何地方,路径都被视为相对于当前命名空间(无论是模块,函数等).

pub mod a {
    use std;

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

您还可以使用use语句导入更具体的项目.例如,你可以写use std::fs::remove_file;.这使您可以避免必须键入整个路径,remove_fileremove_file直接在该模块中使用该名称:

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

    #[test]
    pub fn test() {
        println!("{:?}", remove_file("Somefilehere")));
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以use通过在路径前加上完全避免使用::来请求编译器解决来自crate的根命名空间的路径(即将路径转换为绝对路径).

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

建议的做法是直接导入类型(结构,枚举等)(例如use std::rc::Rc;,然后使用路径Rc),但通过导入其父模块来使用函数(例如use std::io::fs;,然后使用路径fs::remove_file).

pub mod a {
    use std::fs;

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

附注:您还可以self::在路径的开头写入,使其相对于当前模块.这通常用在use语句中,因为其他路径已经是相对的(尽管它们是相对于当前命名空间的,但self::总是相对于包含模块).