【问题标题】:Rust imports: split large file into smaller filesRust 导入:将大文件拆分为小文件
【发布时间】:2021-06-23 23:52:24
【问题描述】:

我正在用 rust 编写一个 TUI 应用程序来管理一些游戏服务器。应用程序本身运行良好,但 main.rs 文件现在超过 1k 行,因此我决定将其拆分为多个文件以使其更易于使用。每个文件都需要能够访问其他文件中的结构和函数。拆分文件具有以下结构。

src \
    main.rs
    render.rs
    ark.rs
    db.rs

这是我当前的 Cargo.toml

[package]
name = "ark-manager"
version = "0.1.0"
authors = ["Nan0Scho1ar <scorch267@gmail.com>"]
edition = "2018"

[dependencies]
crossterm = { version = "0.19", features = [ "serde" ] }
serde = {version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = { version = "0.4", features = ["serde"] }
rand = { version = "0.7.3", default-features = false, features = ["std"] }
tui = { version = "0.14", default-features = false, features = ['crossterm', 'serde'] }
thiserror = "1.0"

我尝试按照我在此处找到的文档进行操作。 https://doc.rust-lang.org/stable/book/ch07-05-separating-modules-into-different-files.html

这让我相信解决方案看起来像这样。

main.rs

mod render;
mod db;
mod ark;

pub use crate::render::*;
pub use crate::db::*;
pub use crate::ark::*;

//Main loop etc
...

ark.rs

pub mod ark {
    pub use crate::render::*;
    pub use crate::db::*;

    //Structs, enums etc
    pub enum Event<I> {
        Input(I),
        Tick
    }
    ...
}

db.rs

pub mod db {
    pub use crate::render::*;
    pub use crate::ark::*;


    //DB functions
    ...
}

render.rs

pub mod render {
    pub use crate::db::*;
    pub use crate::ark::*;

    //Render functions
    ...
}

我还更新了对现在位于单独模块中的事物的引用

//E.G.
if let Ok(_) = tx.send(Event::Tick) {
//Becomes
if let Ok(_) = tx.send(ark::Event::Tick) {
//And
Event::Input(event) => match event.code {
//Becomes
ark::Event::Input(event) => match event.code {

但这导致了以下错误。

error[E0433]: failed to resolve: could not find `Event` in `ark`
  --> src/main.rs:79:45
   |
79 |                 if let Ok(_) = tx.send(ark::Event::Tick) {
   |                                             ^^^^^ could not find `Event` in `ark`

error[E0433]: failed to resolve: could not find `Event` in `ark`
   --> src/main.rs:216:22
    |
216 |                 ark::Event::Input(event) => match event.code {
    |                      ^^^^^ could not find `Event` in `ark`

error[E0433]: failed to resolve: could not find `Event` in `ark`
   --> src/main.rs:226:22
    |
226 |                 ark::Event::Tick => {}
    |                      ^^^^^ could not find `Event` in `ark`

error[E0433]: failed to resolve: could not find `Event` in `ark`
   --> src/main.rs:230:22
    |
230 |                 ark::Event::Input(event) => match event.code {
    |                      ^^^^^ could not find `Event` in `ark`

...

在尝试让它工作一段时间后,我决定看看其他人是如何解决这个问题的,我找到了许多关于堆栈溢出问题的答案,比如这个。 Rust import error 我尝试使用接受的答案中概述的导入,看起来像这样。

main.rs

mod render;
mod db;
mod ark;

//Main loop etc
...

ark.rs

use render;
use db;

//Structs, enums etc
...

db.rs

use render;
use ark;

//DB functions
...

render.rs

use db;
use ark;

//Render functions
...

但是这种结构会导致以下错误。

error[E0432]: unresolved import `db`
 --> src/render.rs:1:9
  |
1 |     use db;
  |         ^^ no external crate `db`

error[E0432]: unresolved import `ark`
 --> src/render.rs:2:9
  |
2 |     use ark;
  |         ^^^ no external crate `ark`

error[E0432]: unresolved import `render`
 --> src/db.rs:1:9
  |
1 |     use render;
  |         ^^^^^^ no external crate `render`

error[E0432]: unresolved import `ark`
 --> src/db.rs:2:9
  |
2 |     use ark;
  |         ^^^ no external crate `ark`

error[E0432]: unresolved import `render`
 --> src/ark.rs:1:9
  |
1 |     use render;
  |         ^^^^^^ no external crate `render`

error[E0432]: unresolved import `db`
 --> src/ark.rs:2:9
  |
2 |     use db;
  |         ^^ no external crate `db`

...

将我的 main.rs 文件拆分为 4 个较小文件的正确方法是什么,以便每个文件都可以使用其他文件中的结构和函数。

【问题讨论】:

  • 您的个人文件不应包含 pub mod X { 包装器。由于main.rs 中的mod X; 行,文件本身已经是一个模块。

标签: import rust


【解决方案1】:

主要:

mod render;
mod db;
mod ark;

然后在其他所有方面:

use crate::render;
use crate::db;
// ...

【讨论】:

  • 我是否需要在每个文件的顶部列出每个结构和函数?如果我尝试use crate::render::*; 之类的东西,它就不起作用。但是如果没有它,编译器似乎建议我每次遇到不同文件中的函数或结构时都需要添加一个导入。换句话说,有没有一种方法可以一次性导入整个文件
  • "如果我尝试使用 crate::render::*; 之类的方法,它就不起作用。" - 在这种情况下有什么错误?如果您在lib.rs 中有mod render;,则此导入应该有效,模名称冲突。
  • 如果我将 use crate::ark::*; 放在 db.rs 的顶部,我会收到类似 could not find 'Event' in 'ark' 的错误。如果我在文件中手动指定每个结构/枚举/函数等,例如use crate::ark::{Event, MenuItem};,那么它工作正常。
  • 事后看来,这可能是我第一次尝试时将Event::Input(event) =&gt; match event.code { 更改为ark::Event::Input(event) =&gt; match event.code { 造成的。我已经撤消了该更改,但我已经手动指定了几乎所有更改。为了向其他人澄清,我将尝试将其注释掉并用简单版本替换它
  • 如果我将use crate::render::{read_db}; 改回use crate::render;,即使函数是公开的,我也会收到错误error[E0425]: cannot find function 'read_db' in this scope。我现在只是手动指定所有内容,但如果还有其他需要测试的内容,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
相关资源
最近更新 更多