Подтвердить что ты не робот

Основной импорт ржавчины (включая)

Я действительно не могу найти, как включать (или импортировать, вводить или smth.) Функцию из одного файла (модуля) в другой.

Вот пример.

Я начинаю новый проект с

cd ~/projects
cargo new proj --bin
cd proj
tree
# output
.
|
-- Cargo.toml
-- src
   |
   -- main.rs

Затем я main.rs и создаю новый файл a.rs (внутри a.rs src) со следующим кодом:

// main.rs
fn main() { println!("{}", a::foo()); }


// a.rs
pub fn foo() -> int { 42i }

Я запускаю проект с cargo run

Здесь у меня две ошибки:

  • src/main.rs: 2: 20: 2:26 Ошибка: не удалось разрешить. Использование незаявленного модуля a
  • src/main.rs: 2: 20: 2:26 error: unresolved name a::foo.

Пока это кажется совершенно очевидным, мне просто нужно каким-то образом импортировать a.

Я попытался добавить следующие вещи в качестве первой строки в main.rs

  • use a; → ошибка: неразрешенный импорт (возможно, вы имели a::* виду a::*?)
  • use a::*; → ошибка: операторы импорта glob являются экспериментальными и, возможно, ошибками
  • use a::foo; → ошибка: неразрешенный импорт a::foo. Может быть, недостающий extern crate a?
  • extern crate a; use a::foo; → Ошибка: не удается найти ящик для a
  • extern crate proj; use proj::a::foo; → ошибка: не удается найти ящик для proj

Я прочитал руководство на ржавчине, но до сих пор не могу понять, как делать импорт.

4b9b3361

Ответ 1

В основном модуле (main.rs, lib.rs или subdir/mod.rs) вам нужно написать mod a; для всех остальных модулей, которые вы хотите использовать во всем проекте (или в поддиректории).

В любом другом модуле вам нужно написать use a; или use a::foo;

Вы далеко не единственный, кого это смущает, и, безусловно, можно добиться большего, но любые изменения в модульной системе будут отклонены как "слишком запутанные".

Изменение: этот ответ был написан для языкового стандарта "Rust 2015". Изменения были внесены в стандарт "Rust 2018", см. Этот пост в блоге.

Ответ 2

В Rust есть несколько ключевых слов для работы с модулями:

extern crate

extern crate заполняет пробел между Cargo и Rust. Мы пишем код в файле .rs, этот файл может быть скомпилирован с помощью rustc. Cargo будет управлять внешними зависимостями и вызывать rustc. Строка extern crate... указывает компилятору искать это пространство имен, поэтому оно однозначно.

Примечание редактора - extern crate не требуется во многих случаях, если вы используете версию Rust 2018.

mod

mod имеет два применения:

  • при использовании с фигурными скобками он объявляет модуль (пространство имен).
  • при использовании только с именем, он будет искать модуль в локальной файловой системе.

Модули могут быть:

  • файлы с расширением .rs
  • папки с одним файлом с именем mod.rs

use

use импортирует пространство имен. Мы должны объявить, что мы собираемся использовать, прежде чем использовать его. Предложение use довольно строгое, если мы use module1::moduleA; Никакой другой модуль из модуля module1 не будет доступен, кроме moduleA Звездочка (*) может использоваться для использования всего в модуле: use module1::*; , Также можно использовать наборы: use module1::{moduleA, moduleB};

Пример:

| main.rs
|- module1
      |- mod.rs
      |- moduleA.rs
      |- moduleB.rs

mod.rs содержит:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module

main.rs содержит:

///  ======
// use what Cargo downloaded
extern crate that_one_thing_i_need;

///  ======

mod module1; // declare a child module

// some local stuff I want to scope
mod local {
    pub fn my_function() {}
}

//   ======

// make the symbols locally available:
use module1::moduleA::*;
use module1::moduleB::{functionX, moduleY, typeZ};

// we still need to announce what stuff from the external crate
// we want to use:
// We can do local aliases that will be valid in this one file.
use that_one_thing_i_need::fancy_stuff as fs;

///  ======

fn main() {
    // we can use anything here from the namespaces we are using:
    //      moduleA
    //      functionX
    //      moduleY
    //      typeZ
    //      fs

    // We can access stuff by navigating from the outermost visible
    // module name
    local::my_function();
}

Символы можно использовать только из модуля. Если вы хотите преодолеть этот барьер (даже в локально объявленном модуле), нам нужно сделать их общедоступными с помощью ключевого слова pub.