我有以下代码:
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"));
}
答案 0 :(得分:38)
默认情况下,编译器在crate根的开头插入extern crate std;
(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"));
}
}
您还可以使用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
来避免使用::
来请求编译器解析来自包的根命名空间的路径(即将路径转换为绝对路径)。 / p>
pub mod a {
#[test]
pub fn test() {
println!("{:?}", ::std::fs::remove_file("Somefilehere"));
}
}
建议的做法是直接导入类型(结构,枚举等)(例如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"));
}
}
旁注:您还可以在路径的开头写入self::
,使其相对于当前模块。这在use
语句中更常用,因为其他路径已经是相对的(虽然它们是相对于当前的命名空间,而self::
总是相对于包含模块)。
答案 1 :(得分:1)
如今,std
可以从任何地方直接访问,因此您显示的代码正在按您的期望进行编译。
此外,Rust Edition 2018不再需要extern crate
。向Cargo.toml
添加依赖项可以直接将箱子名称用作顶级标识符。