Rust *准确地*如何查找模块?

Tes*_*est 1 module rust

Rust 用于从文件中查找模块的确切规则集是什么?

我在网上找到的关于模块的每一个解释都说,“这是模块的目的,这是一个例子,……”没有一个给出关于 rust 如何查找模块的完整、全面、100% 准确的解释。即使 Rust参考也没有告诉您板条箱根和导入文件是否都需要声明mod!没有简单的规则集可以用来判断它是否有效。

我正在寻找可以遵循的东西,例如:

  1. Rust 看名字,解析::就像subdir::subdir::name
  2. Rust 会查看name.rs同一目录中是否有文件,并且name/mod.rs
  3. 不允许同时存在 aname.rs和 a name/mod.rs
  4. 然后,鲁斯特...???

Pit*_*taJ 5

这最好从内联模块开始解释。模块从 crate 根开始按层次结构排列。每个板条箱在脱糖后看起来都是这样的:

// root

pub mod a {
    pub mod b {
        pub const X: u8 = 1;
    }
}

mod foo {
    
}
Run Code Online (Sandbox Code Playgroud)

引用树中的项目非常简单:

  • ::“下降”一个级别
  • super::“上升”一个层次
  • crate::转到根级别

参考示例X

  • a::b::X从板条箱根部开始
  • crate::a::b::X从板条箱中的任何地方
  • super::a::b::X从模块内foo
  • b::X从模块内a

mod foo;实际上只是以下任一内容的语法糖:

#[path = "foo.rs"]
mod foo;
// or
#[path = "foo/mod.rs"]
mod foo;
Run Code Online (Sandbox Code Playgroud)

进一步脱糖:

mod foo {
    include!("foo.rs");
}
// or
mod foo {
    include!("foo/mod.rs");
}
Run Code Online (Sandbox Code Playgroud)

如果foo.rs(或foo/mod.rs) 包含 amod bar;那么整个树将如下所示:

mod foo {
    mod bar {
        // contents of `bar.rs` (or `foo/bar/mod.rs`)
    }

    // remaining contents of `foo.rs`
}
Run Code Online (Sandbox Code Playgroud)

mod.rs请注意,尽管仍受支持,但不鼓励使用。相反,建议使用foo.rsforcrate::foo并将其任何子模块放置foofoo/目录中。

如果 和src/foo/mod.rssrc/foo.rs存在,编译器将抛出以下错误:

error[E0761]: file for module `foo` found at both "src\foo.rs" and "src\foo\mod.rs"
 --> src\main.rs:1:1
  |
1 | mod foo;
  | ^^^^^^^^
  |
  = help: delete or rename one of them to remove the ambiguity
Run Code Online (Sandbox Code Playgroud)

crate::总是对应于当时正在编译的包的根模块。如果您的板条箱足够复杂或不遵循约定,则某些crate::...项目路径可以引用不同文件中的不同内容。但通过遵循约定可以轻松避免混乱。

以下是我用来避免混淆的约定列表:

  • 避免#[path]属性
  • 总是使用src/foo.rs而不是src/foo/mod.rs
  • 如果您有多个根模块(例如库和二进制板条箱),它们都应该直接位于src
  • 尽量减少花哨的配置Cargo.toml,尽可能使用默认值