当使用Rust 2018中的模块时,如何解决“根目录中没有模块”的错误?

16
我正在开发一个项目,该项目利用了位于src/文件夹下的一些本地模块。我目前正在使用Rust 2018版,其中一个主要变化是处理导入/use语句
我的模块代码都可以正常工作,但当我开始将其整合为整个项目使用时,我开始遇到以下错误:
error[E0432]: unresolved import `crate::lexer`
 --> src/main.rs:1:5
  |
1 | use crate::lexer;
  |     ^^^^^^^^^^^^ no `lexer` in the root

目前,我的代码设置如下:

src/
 | main.rs
 | lexer/
    | mod.rs
    | lexer.rs

lexer/lexer.rs

pub fn lex_stuff() -> Vec<String> { vec![String::new("test")] }

lexer/mod.rs

pub mod lexer;

main.rs

use crate::lexer;

fn main() {
    println!("Hello, world!");
    lexer::lexer::lex_stuff();
}

我尝试通过将语句更改为 use lexer 以及 use self::lexer 并添加 extern crate lexer(显然不起作用,但是我想试试)。 然而,这些都没有起作用。

我该怎么解决 no 'lexer' in the root 错误?

3个回答

19

我最终弄清楚了这个问题,之前还没有时间回来创建一个解释答案。我误解了先前答案中的链接,并认为它已被 use crate::... 替换。 - RPiAwesomeness
我只在一个lib.rs文件中使用它,为什么还需要这个? - user2997204

4
您需要将mod.rs移动到lexer.rs:
src/
 | main.rs
 | lexer.rs
 | lexer/
    | lexer.rs
    | tokens.rs

这个变化在这里描述:这里

我已经这样做了,保持lexer.rs(之前是lexer/mod.rs)的内容不变,但我仍然得到相同的错误。 - RPiAwesomeness

3

大多数初学者(比如我)想要做的是将一些函数从一个文件(如lib.rs)移动到名为submod.rs的文件中,并在其中访问这些函数,例如submod::myfunc。启发我写这篇文章的答案建议使用lexer::lexer::lex_stuff(),这有点令人恼火。我们不应该没有充分理由地看到两次相同的名称。而像书中使用hosting这样添加另一个名称并没有帮助,因为命名是计算机科学中的难题。

因此,以下是如何制作薄饼而不是一堆薄饼的方法(使用书中的示例):

lib.rs

mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
    front_of_house::seating_capacity();
    hosting::add_to_waitlist();
}

front_of_house.rs(或可选的front_of_house/mod.rs)

pub fn seating_capacity() {}

pub mod hosting {
    pub fn add_to_waitlist() {}
}

现在,如果你在lib.rs中添加一个pub fn put_up_chairs() {},然后决定,等一下,这应该属于front_of_house(但不是hosting),你可以简单地将函数移动到front_of_house.rs中,并在lib.rs中引用它为front_of_house::put_up_chairs()。简单吧?我希望是这样的。我写这篇文章是为了未来的自己,当我忘记这个问题并再次找到这篇文章时,而不是为了您,亲爱的读者。
请注意,当pub关键字消失或更改时,所有事情都变得更加有趣,此时您可能需要重新阅读本书。 ;)
还有一件事,就是在mod front_of_house之后添加pub use front_of_house;是错误的,因为您已经声明了该模块。如果您这样做,Cargo会发出响亮的回答(因为它认为您知道自己在做什么,如果您像我一样通过敲打石头来编程,那么您不知道)。
error[E0255]: the name `front_of_house` is defined multiple times
 --> src/lib.rs:2:9
  |
1 | mod front_of_house;
  | ------------------- previous definition of the module `front_of_house` here
2 | pub use crate::front_of_house;
  |         ^^^^^^^^^^^^^^^^^^^^^ `front_of_house` reimported here
  |
  = note: `front_of_house` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
  |
2 | pub use crate::front_of_house as other_front_of_house;
  |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0365]: `front_of_house` is only public within the crate, and cannot be re-exported outside
 --> src/lib.rs:2:9
  |
2 | pub use crate::front_of_house;
  |         ^^^^^^^^^^^^^^^^^^^^^ re-export of crate public `front_of_house`
  |
  = note: consider declaring type or module `front_of_house` with `pub`

如果你犯了上面所说的“双重使用”的错误,没关系。有点奇怪的是,mod 关键字也为你提供了一个免费的 use。但它确实存在,我们应该感激它。:)

动机

十多年来,我从未在 Stack Overflow 上撰写过答案。但是我已经遇到这个问题很多次,并且被敬爱的 Rust 大师 @Shepmaster 的“请花时间重新阅读”回答弄得非常困惑,所以我写了一个答案。至少在第二版中,Rust Book 的示例就像制作千层蛋糕之前展示做一个薄饼一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接