Bagaimana cara memasukkan modul dari file lain dari proyek yang sama?

130

Dengan mengikuti panduan ini saya membuat proyek Cargo.

src/main.rs

fn main() {
    hello::print_hello();
}

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}

yang saya jalankan menggunakan

cargo build && cargo run

dan dikompilasi tanpa kesalahan. Sekarang saya mencoba untuk membagi modul utama menjadi dua tetapi tidak dapat menemukan cara menyertakan modul dari file lain.

Pohon proyek saya terlihat seperti ini

├── src
    ├── hello.rs
    └── main.rs

dan konten file:

src/main.rs

use hello;

fn main() {
    hello::print_hello();
}

src/hello.rs

mod hello {
    pub fn print_hello() {
        println!("Hello, world!");
    }
}

Ketika saya mengkompilasinya dengan cargo buildsaya dapatkan

error[E0432]: unresolved import `hello`
 --> src/main.rs:1:5
  |
1 | use hello;
  |     ^^^^^ no `hello` external crate

Saya mencoba mengikuti saran penyusun dan memodifikasi main.rsmenjadi:

#![feature(globs)]

extern crate hello;

use hello::*;

fn main() {
    hello::print_hello();
}

Tapi ini masih tidak banyak membantu, sekarang saya mengerti:

error[E0463]: can't find crate for `hello`
 --> src/main.rs:3:1
  |
3 | extern crate hello;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

Apakah ada contoh sepele tentang bagaimana memasukkan satu modul dari proyek saat ini ke dalam file utama proyek?

ave
sumber
1
kemungkinan duplikat impor dasar Rust (termasuk)
Levans

Jawaban:

239

Anda tidak perlu mod hellodi hello.rsfile Anda . Kode dalam file apa pun kecuali akar peti ( main.rsuntuk file yang dapat dieksekusi, lib.rsuntuk perpustakaan) secara otomatis diberi spasi dalam modul.

Untuk memasukkan kode dari hello.rsdalam Anda main.rs, gunakan mod hello;. Itu diperluas ke kode yang ada hello.rs(persis seperti yang Anda miliki sebelumnya). Struktur file Anda tetap sama, dan kode Anda perlu sedikit diubah:

main.rs:

mod hello;

fn main() {
    hello::print_hello();
}

hello.rs:

pub fn print_hello() {
    println!("Hello, world!");
}
Renato Zannon
sumber
1
Pertanyaan Terlambat bukankah ini juga akan berfungsi jika saya menentukannya dengan use hello, bukan mod hello ?!
Christian Schmitt
16
@ChristianSchmitt Tidak, mereka berbeda. usehanyalah sebuah namespace, sementara modmenarik file tersebut. Anda akan menggunakan use, misalnya, untuk dapat memanggil print_hellofungsi tanpa harus
mengawali
25

Jika Anda ingin memiliki modul bersarang ...

Karat 2018

Ini tidak lagi diperlukan untuk memiliki file mod.rs(meskipun masih didukung). Alternatif idiomatik adalah memberi nama file dengan nama modul:

$ tree src
src
├── main.rs
├── my
│   ├── inaccessible.rs
│   └── nested.rs
└── my.rs

main.rs

mod my;

fn main() {
    my::function();
}

my.rs

pub mod nested; // if you need to include other modules

pub fn function() {
    println!("called `my::function()`");
}

Karat 2015

Anda perlu meletakkan mod.rsfile di dalam folder Anda dengan nama yang sama dengan modul Anda. Rust by Example menjelaskannya dengan lebih baik.

$ tree src
src
├── main.rs
└── my
    ├── inaccessible.rs
    ├── mod.rs
    └── nested.rs

main.rs

mod my;

fn main() {
    my::function();
}

mod.rs

pub mod nested; // if you need to include other modules

pub fn function() {
    println!("called `my::function()`");
}
amxa
sumber
4
Misalkan saya ingin menggunakan sesuatu dari inaccessible.rsdalam nested.rs... bagaimana saya melakukannya?
Heman Gandhi
Untuk mengakses file saudara kandung dari file selain main.rs, gunakan atribut path. Jadi, di bagian atas nested.rs, tambahkan berikut ini: #[path = "inaccessible.rs"]dan di baris berikutnya:mod inaccessible;
Gardener
@Gandhi Lihat Atribut jalan
Gardener
2
@HemanGandhi tambahkan mod inaccessible;ke my/mod.rsmembuatnya menjadi submodul my, lalu akses modul saudara dari nested.rsjalur relatif super::inaccessible::function(). Anda tidak membutuhkan pathatribut di sini.
Artin
9

Saya sangat menyukai tanggapan Gardener. Saya telah menggunakan saran untuk deklarasi modul saya. Seseorang mohon bergabung jika ada masalah teknis dengan ini.

./src
├── main.rs
├── other_utils
│   └── other_thing.rs
└── utils
    └── thing.rs

main.rs

#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;

fn main() {
  thing::foo();
  other_thing::bar();
}

utils / thing.rs

pub fn foo() {
  println!("foo");
}

other_utils / other_thing.rs

#[path = "../utils/thing.rs"] mod thing;

pub fn bar() {
  println!("bar");
  thing::foo();
}
rodo
sumber
Harus menggunakan 'trik' ini untuk mengekspor ulang fndengan nama yang sama dengan file itu masuk#[path = "./add_offer.rs"] mod _add_offer; pub use self::_add_offer::add_offer;
Arek Bal
ini harus menjadi jawaban yang diterima imo
Homam Bahrani