Вызов кросс-модульной функции в Rust - PullRequest
2 голосов
/ 02 апреля 2020

Я пытаюсь вызвать функцию, принадлежащую одному модулю из другого модуля (для факторинга кода, организация, et c).

Вот моя структура ящика:

➜  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");}.

На данный момент все хорошо .

Теперь можно ли позвонить lib::two::main с bin/one.rs?

Ни один из 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-generi c, для чего это стоит.

  • edit 2: при использовании ключевого слова super я получаю эту загадочную ошибку от rustc:

error[E0433]: failed to resolve: there are too many leading `super` keywords

и не могу найти любую неисправность по этому поводу в любом месте.

  • edit 3: добавление файла lib.rs в src с объявлением структуры модуля lib и запись use mod_test::lib::two; в one.rs работает, но:

    1) он побеждает идею не умножать «файлы объявлений тупых модулей» в моем ящике.

    2) Я должен буквально копировать одну и ту же информацию в двух разных местах (в main.rs и в lib.rs)

    3) use mod_test::lib::two; - единственный рабочий синтаксис, использующий crate или super ключевые слова по-прежнему приводят к непонятным ошибкам компилятора

1 Ответ

3 голосов
/ 02 апреля 2020

src/bin - это специальное имя каталога для Car go. Файлы в этом каталоге компилируются как автономные двоичные файлы при запуске cargo build. При компиляции в виде двоичных файлов они не являются частью структуры ящика, определенной в main.rs или lib.rs.

Если вы просто хотите использовать bin::one в качестве модуля внутри main.rs, то, что у вас есть работает уже! Вы получаете сообщения об ошибках при компиляции one.rs в виде отдельного двоичного файла, а не при компиляции main.rs с bin::one в качестве модуля. Если вы запустите cargo run --bin <name-of-project>, компиляция будет выполнена успешно, и она запустит программу в main.rs.

Чтобы сказать Car go, что он не компилирует one.rs, я бы предложил переименовать bin каталог. Это не только решает техническую проблему, но и с меньшей вероятностью запутает других программистов, читающих проект, которые ожидают, что bin будет содержать двоичные файлы. Может быть какой-то способ помешать Car go специально обработать bin таким образом; однако, переименование это, вероятно, лучший вариант.

Если вы do хотите скомпилировать one.rs в отдельный исполняемый файл, использующий two, вы должны создать файл lib.rs в том же каталоге, что и main.rs. Это также специальный файл для Car go, который определяет структуру модуля для ящика библиотеки.

// 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 компилируются как автономные двоичные файлы, а не как члены ящика; поэтому вы должны вызывать ящик по его «внешнему» имени.

, добавив файл lib.rs в sr c, объявив структуру модуля lib и написав use mod_test :: lib :: два; в one.rs работает, но:

1) он побеждает идею не умножать «файлы декларации тупого модуля» в моем ящике.

2) Я должен буквально копировать ту же самую информацию в двух разных местах (в main.rs и в lib.rs)

main.rs и lib.rs - два разных корня ящика . Им разрешено иметь разную структуру. Вам не нужны оба, если вы не хотите генерировать двоичный файл и библиотеку. Если вы хотите использовать ящик библиотеки из любого двоичного файла (включая main.rs), он находится на расстоянии use:

use mod_test;

См. Также

...