gpt4 book ai didi

rust - 你如何在 Rust 中使用父模块导入?

转载 作者:行者123 更新时间:2023-11-29 08:33:17 24 4
gpt4 key购买 nike

如果你有这样的目录结构:

src/main.rs
src/module1/blah.rs
src/module1/blah2.rs
src/utils/logging.rs

如何使用其他文件中的函数?

根据 Rust 教程,听起来我应该能够做到这一点:

ma​​in.rs

mod utils { pub mod logging; }
mod module1 { pub mod blah; }

fn main() {
utils::logging::trace("Logging works");
module1::blah::doit();
}

logging.rs

pub fn trace(msg: &str) {
println!(": {}\n", msg);
}

blah.rs

mod blah2;
pub fn doit() {
blah2::doit();
}

blah2.rs

mod utils { pub mod logging; }
pub fn doit() {
utils::logging::trace("Blah2 invoked");
}

但是,这会产生一个错误:

error[E0583]: file not found for module `logging`
--> src/main.rs:1:21
|
1 | mod utils { pub mod logging; }
| ^^^^^^^
|
= help: name the file either logging.rs or logging/mod.rs inside the directory "src/utils"

似乎沿着路径导入,即从 mainmodule1/blah.rs 有效,并导入对等点,即 blah2blah 有效,但从父作用域导入无效。

如果我使用神奇的 #[path] 指令,我可以完成这项工作:

blah2.rs

#[path="../utils/logging.rs"]
mod logging;

pub fn doit() {
logging::trace("Blah2 invoked");
}

我真的必须手动使用相对文件路径从父范围级别导入内容吗?在 Rust 中没有更好的方法来做到这一点吗?

在 Python 中,您可以使用 from .blah import x 作为局部作用域,但如果您想访问绝对路径,您可以使用 from project.namespace.blah import x.

最佳答案

我也将回答这个问题,以供发现此问题并且(像我一样)对难以理解的答案感到完全困惑的任何人。

归结为我觉得本教程中没有解释清楚的两件事:

  • mod blah; 语法为编译器导入一个文件。您必须对所有要编译的文件使用它

  • 与共享库一样,任何定义的本地模块都可以使用 use blah::blah; 导入到当前范围。

一个典型的例子是:

src/main.rs
src/one/one.rs
src/two/two.rs

在这种情况下,您可以使用 usetwo.rs 中获取 one.rs 中的代码:

use two::two;  // <-- Imports two::two into the local scope as 'two::'

pub fn bar() {
println!("one");
two::foo();
}

但是,main.rs 必须是这样的:

use one::one::bar;        // <-- Use one::one::bar 
mod one { pub mod one; } // <-- Awkwardly import one.rs as a file to compile.

// Notice how we have to awkwardly import two/two.rs even though we don't
// actually use it in this file; if we don't, then the compiler will never
// load it, and one/one.rs will be unable to resolve two::two.
mod two { pub mod two; }

fn main() {
bar();
}

请注意,您可以使用 blah/mod.rs 文件来稍微缓解这种尴尬,方法是放置一个类似 one/mod.rs 的文件,因为 mod x; 尝试将 x.rsx/mod.rs 作为负载。

// one/mod.rs
pub mod one.rs

您可以将 main.rs 顶部笨拙的文件导入减少到:

use one::one::bar;       
mod one; // <-- Loads one/mod.rs, which loads one/one.rs.
mod two; // <-- This is still awkward since we don't two, but unavoidable.

fn main() {
bar();
}

Github 上有一个示例项目正在执行此操作.

值得注意的是,模块独立于包含代码块的文件;虽然加载文件 blah.rs 的唯一方法似乎是创建一个名为 blah 的模块,但您可以使用 #[path] 解决这个问题,如果你出于某种原因需要的话。不幸的是,它似乎不支持通配符,将来自多个文件的函数聚合到一个顶级模块中是相当乏味的。

关于rust - 你如何在 Rust 中使用父模块导入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42154376/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com