Как устранить ошибку "нет модуля в корне" при использовании модуля в Rust 2018?
Я работаю над проектом, который использует некоторые локальные модули в папках под 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.rs
pub fn lex_stuff() -> Vec<String> { vec![String::new("test")] }
лексер / 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 ответа
Вам все еще нужно объявить, что main.rs содержит модуль:
mod lexer; // This, not `use`
fn main() {
println!("Hello, world!");
lexer::lexer::lex_stuff();
}
Пожалуйста, уделите время перечитыванию языка программирования Rust, в частности, раздела о разделении модулей на разные файлы.
Вы должны двигаться mod.rs
в lexer.rs
:
src/
| main.rs
| lexer.rs
| lexer/
| lexer.rs
| tokens.rs
Это изменение описано здесь.
То, что большинство новичков (ака я постоянно) хотят сделать, это переместить некоторые функции из одного файла, например, в файл с именемsubmod.rs
и получить доступ к функциям в нем какsubmod::myfunc
. Ответ, который вдохновил меня написать это, предполагаетlexer::lexer::lex_stuff()
что немного бесит. Мы никогда не должны видеть имя дважды без серьезной причины. И добавление другого имени, как это делается в книге, бесполезно, поскольку именование - сложная проблема в CS.
Итак, вот как сделать блин вместо стопки блинов (на примере из книги):
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() {}
}
Теперь, если вы добавитеpub fn put_up_chairs() {}
и решить, подожди минутку, что принадлежитfront_of_house
(но нетhosting
), вы можете просто переместить функцию вfront_of_house.rs
и обратитесь к нему вlib.rs
какfront_of_house::put_up_chairs()
. Простой..? Я надеюсь? Я пишу себе в будущее, когда забуду это и снова найду этот ответ, а не вам, любезный читатель.
Обратите внимание, что все становится более захватывающим, когдаpub
ключевое слово пропало или изменено, и в этот момент, возможно, вам следует перечитать книгу. ;)
И еще одно, добавивpub use front_of_house;
послеmod front_of_house
ошибка, потому что вы уже объявили модуль. Если вы делаете груз, вы даете громкий ответ (потому что предполагается, что вы знаете, что делаете, если вы, как я, программируете компьютеры, разбивая камни друг о друга, вы этого не знаете)
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
бесплатно. Но это так, и мы должны быть благодарны за это. :)
Мотивация
За более чем десятилетие я никогда не писал ответа на SO. Но я задавал этот вопрос так много раз и был настолько сбит с толку ответом «Пожалуйста, найдите время, чтобы перечитать» любимого мастера ржавчины @Shepmaster, что я пишу ответ. Пример Rust Book похож на рецепт выпечки блинного пирога, прежде чем показать вам, как сделать один блинчик, по крайней мере, во 2-м издании.