简体   繁体   中英

How *exactly* does rust look up modules?

What is the exact set of rules that rust uses to look up a module from a file?

Every explanation I have found online about modules says, "this is the purpose of modules, here is an example of one, ..." None give the complete, comprehensive, 100% accurate explanation for how rust looks up modules . Even the rust reference doesn't tell you whether both the crate root and the importing file need to declare mod . There is no simple ruleset I can use to tell whether it will work.

I'm looking for something I can follow, like:

  1. Rust looks at the name, parsing :: like subdir::subdir::name
  2. Rust looks to see if there is a file name.rs in the same directory and name/mod.rs
  3. There is not allowed to be both a name.rs and a name/mod.rs .
  4. Then, Rust...???

This is best explained starting from inline modules. Modules are arranged into a hierarchy from the crate root. Every crate, after some desugaring, looks something like this:

// root

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

mod foo {
    
}

Referring to an item in the tree is pretty simple:

  • :: goes "down" a level
  • super:: goes "up" a level
  • crate:: goes to the root level

Examples for referring to X :

  • a::b::X from the crate root
  • crate::a::b::X from anywhere in the crate
  • super::a::b::X from within module foo
  • b::X from within module a

mod a; is really just syntax sugar for either of the following:

#[path = "foo.rs"]
mod foo;
// or
#[path = "foo/mod.rs"]
mod foo;

Which further desugar to:

mod foo {
    include!("foo.rs");
}
// or
mod foo {
    include!("foo/mod.rs");
}

If foo.rs (or foo/mod.rs ) contains a mod bar; then the whole tree would look like:

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

    // remaining contents of `foo.rs`
}

Please note that the usage of mod.rs , while still supported, is discouraged. Instead, it's recommended to use foo.rs for crate::foo and place any submodules of foo in the foo/ directory.

crate:: just always corresponds to the root being compiled at the time. If your crate is sufficiently complex or doesn't follow convention, then certain crate::... item paths can refer to different things in different files. But confusion is easily avoidable by following conventions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM