Rust 中的跨模块函数调用

War*_*pig 6 module code-organization rust rust-crates

我正在尝试从另一个模块调用属于某个模块的函数(用于代码分解、组织)。

这是我的箱子结构:

?  mod_test git:(master) ? tree
.
??? Cargo.lock
??? Cargo.toml
??? src
    ??? bin
    ?   ??? one.rs
    ??? lib
    ?   ??? two.rs
    ??? main.rs

3 directories, 5 files
Run Code Online (Sandbox Code Playgroud)

main我声明:

pub mod bin {
    pub mod one;
}
pub mod lib {
    pub mod two;
}
Run Code Online (Sandbox Code Playgroud)

所有这些文件只包含一个微不足道的 pub fn main() {println!("hello");}.

此时,一切正常

现在,是它可以调用lib::two::mainbin/one.rs

use crate::lib::two;, use super::lib::two;, 都没有use self::super::lib::two;添加到bin/one.rs工作中。


  • 编辑:我有:rustc 1.42.0 (b8cedc004 2020-03-09)安装在 Linux 5.3.0-45-generic 上,这是值得的。

  • 编辑 2:每当使用super关键字时,我都会从rustc以下位置收到这个神秘的错误:

error[E0433]: failed to resolve: there are too many leading `super` keywords
Run Code Online (Sandbox Code Playgroud)

我在任何地方都找不到任何关于此的故障排除。

  • 编辑3:lib.rssrc声明lib模块结构中添加一个文件,并use mod_test::lib::two;one.rs作品中写入,但是:

    1)它破坏了不在我的箱子中增加“哑模块声明文件”的想法。

    2)我必须在两个不同的地方(inmain.rs和 in )逐字复制完全相同的信息lib.rs )

    3)use mod_test::lib::two;是唯一有效的语法,使用crateorsuper关键字仍然会导致神秘的编译器错误

tre*_*tcl 7

src/bin is a special directory name to Cargo. Files in this directory are compiled as standalone binaries when you run cargo build. When compiled as binaries, they aren't part of the crate structure defined in main.rs or lib.rs.

If you just want to use bin::one as a module inside main.rs, what you have works already! You're getting error messages from compiling one.rs as a standalone binary, not from compiling main.rs with bin::one as a module. If you run cargo run --bin <name-of-project>, compilation will succeed and it will run the program in main.rs.

To tell Cargo not to compile one.rs by itself, I would suggest renaming the bin directory. This not only solves the technical problem, but also is less likely to confuse other programmers reading the project, who will expect bin to contain binaries. There may be some way to prevent Cargo from treating bin specially in this way; however, renaming it is probably the best option.

If you do want one.rs to be compiled to a separate executable that uses two, you must create a lib.rs file in the same directory as main.rs. This is also a special file to Cargo and it defines the module structure for the library crate.

// lib.rs
pub mod lib { /* note: this lib is not related to lib.rs; just unfortunately named */
    pub mod two;
}
Run Code Online (Sandbox Code Playgroud)

Then inside one.rs, write use <crate-name>::lib::two;

// bin/one.rs
use mod_test::lib::two;
Run Code Online (Sandbox Code Playgroud)

crate::lib::two does not work, as files inside the bin directory are compiled as standalone binaries, not as crate members; therefore, you have to call the crate by its "external" name.

adding a lib.rs file in src declaring the lib module structure, and writing use mod_test::lib::two; in one.rs works, but:

1) it defeats the idea of not multiplying "dumb module declaration files" in my crate.

2) I have to literally copy the exact same information at two different places (in main.rs and in lib.rs)

main.rs and lib.rs are two different crate roots. They are allowed to have different structure. You don't need both unless you want to generate both the binary and the library. If you want to use the library crate from inside any binary (including main.rs), it's just a use away:

use mod_test;
Run Code Online (Sandbox Code Playgroud)

See also