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 根目录的开头插入(板条箱根目录是您传递给的文件rustc)。该语句的作用是将名称添加std到 crate 的根命名空间,并将其与包含stdcrate 的公共内容的模块相关联。

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

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

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通过在路径前加上前缀::来要求编译器解析来自 crate 的根命名空间的路径(即将路径转换为绝对路径),从而完全避免使用。

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

推荐的做法是直接导入类型(结构、枚举等)(例如use std::rc::Rc;,然后使用 path Rc),但通过导入其父模块来使用函数(例如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,因为其他路径已经是相对的(尽管它们是相对于当前的namespace,而self::总是相对于包含的module)。

于 2014-05-02T18:57:35.677 回答
2

如今,std可以从任何地方直接访问,因此您显示的代码正在按照您的预期进行编译。

此外,extern crateRust 2018 版不再需要它。添加依赖项以Cargo.toml使 crate 名称直接用作顶级标识符。

于 2020-10-27T20:04:14.123 回答