【问题标题】:Cross-module function call in RustRust 中的跨模块函数调用
【发布时间】:2020-04-02 14:13:56
【问题描述】:

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

这是我的箱子结构:

➜  mod_test git:(master) ✗ tree
.
├── Cargo.lock
├── Cargo.toml
└── src
    ├── bin
    │   └── one.rs
    ├── lib
    │   └── two.rs
    └── main.rs

3 directories, 5 files

main我声明:

pub mod bin {
    pub mod one;
}
pub mod lib {
    pub mod two;
}

所有这些文件都只包含一个琐碎的pub fn main() {println!("hello");}

此时,一切都正常

现在,可以从bin/one.rs 拨打lib::two::main 吗?

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

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

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

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

    2) 我必须在两个不同的地方复制完全相同的信息(main.rslib.rs

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

【问题讨论】:

    标签: module rust code-organization rust-crates


    【解决方案1】:

    src/bin 是 Cargo 的特殊目录名称。当您运行cargo build 时,此目录中的文件将编译为独立的二进制文件。当编译为二进制文件时,它们不是 main.rslib.rs 中定义的 crate 结构的一部分。

    如果你只是想将bin::one 用作main.rs 中的一个模块,那么你所拥有的已经可以了!您从将 one.rs 编译为独立二进制文件而不是从将 main.rsbin::one 作为模块编译时收到错误消息。如果运行cargo run --bin <name-of-project>,编译成功,会运行main.rs中的程序。

    为了告诉 Cargo 不要自己编译 one.rs,我建议重命名 bin 目录。这不仅解决了技术问题,而且不太可能混淆阅读该项目的其他程序员,他们会期望bin 包含二进制文件。可能有一些方法可以防止 Cargo 以这种方式特别对待bin;但是,重命名它可能是最好的选择。

    如果您确实希望将one.rs 编译为使用two 的单独可执行文件,则必须在与main.rs 相同的目录中创建lib.rs 文件。这也是 Cargo 的一个特殊文件,它定义了库 crate 的模块结构。

    // lib.rs
    pub mod lib { /* note: this lib is not related to lib.rs; just unfortunately named */
        pub mod two;
    }
    

    然后在one.rs里面写use <crate-name>::lib::two;

    // bin/one.rs
    use mod_test::lib::two;
    

    crate::lib::two 工作,因为bin 目录中的文件被编译为独立的二进制文件,而不是作为 crate 成员;因此,您必须通过它的“外部”名称来调用板条箱。

    在 src 中添加一个 lib.rs 文件,声明 lib 模块结构,并编写 use mod_test::lib::two;在 one.rs 中有效,但是:

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

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

    main.rslib.rs两个不同的 crate 根。它们被允许具有不同的结构。除非您想同时生成二进制文件和库,否则您不需要两者。如果您想使用任何二进制文件(包括main.rs)中的库板条箱,只需use

    use mod_test;
    

    另见

    【讨论】:

    • 非常感谢!我想我对创建 bin/ 和 lib/ 会导致两个不同的 crate 根的事实感到困惑。
    猜你喜欢
    • 2022-08-21
    • 1970-01-01
    • 2017-07-24
    • 2018-01-28
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多