Làm thế nào để bao gồm một mô-đun từ một tệp khác từ cùng một dự án?


130

Bằng cách làm theo hướng dẫn này, tôi đã tạo một dự án Hàng hóa.

src/main.rs

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

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

cái mà tôi chạy bằng cách sử dụng

cargo build && cargo run

và nó biên dịch không có lỗi. Bây giờ tôi đang cố gắng chia mô-đun chính thành hai nhưng không thể tìm ra cách bao gồm một mô-đun từ một tệp khác.

Cây dự án của tôi trông như thế này

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

và nội dung của các tệp:

src/main.rs

use hello;

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

src/hello.rs

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

Khi tôi biên dịch nó với cargo buildtôi nhận được

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

Tôi đã cố gắng làm theo các đề xuất của trình biên dịch và sửa đổi main.rsthành:

#![feature(globs)]

extern crate hello;

use hello::*;

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

Nhưng điều này vẫn không giúp được nhiều, bây giờ tôi nhận được điều này:

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

Có một ví dụ đơn giản nào về cách đưa một mô-đun từ dự án hiện tại vào tệp chính của dự án không?


1
bản sao có thể có của nhập khẩu cơ bản Rust (bao gồm)
Levans

Câu trả lời:


239

Bạn không cần tệp mod hellocủa mình hello.rs. Mã trong bất kỳ tệp nào nhưng gốc thùng ( main.rsđối với tệp thực thi, lib.rsđối với thư viện) được đặt tên tự động trong một mô-đun.

Để bao gồm mã từ hello.rstrong của bạn main.rs, hãy sử dụng mod hello;. Nó được mở rộng thành mã có trong hello.rs(chính xác như bạn đã có trước đây). Cấu trúc tệp của bạn vẫn tiếp tục như cũ và mã của bạn cần được thay đổi một chút:

main.rs:

mod hello;

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

hello.rs:

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

1
Câu hỏi muộn sẽ không hoạt động nếu tôi chỉ định nó bằng cách sử dụng hello thay vì mod hello ?!
Christian Schmitt

16
@ChristianSchmitt Không, chúng là những thứ khác nhau. usechỉ là một thứ không gian tên, trong khi modkéo tệp vào. Bạn sẽ sử dụng use, ví dụ, để có thể gọi là print_hellochức năng mà không cần phải tiền tố với namespace
Renato Zannon

25

Nếu bạn muốn có các mô-đun lồng nhau ...

Gỉ 2018

Không còn bắt buộc phải có tệp mod.rs(mặc dù nó vẫn được hỗ trợ). Cách thay thế thành ngữ là đặt tên tệp bằng tên của mô-đun:

$ 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()`");
}

Rỉ sét 2015

Bạn cần đặt một mod.rstệp bên trong thư mục có cùng tên với mô-đun của bạn. Rust by Ví dụ giải thích nó tốt hơn.

$ 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()`");
}

4
Giả sử tôi muốn sử dụng một cái gì đó từ inaccessible.rstrong nested.rs... tôi sẽ làm điều đó như thế nào?
Heman Gandhi

Để truy cập tệp .rs anh chị em từ tệp không phải là main.rs, hãy sử dụng thuộc tính đường dẫn. Vì vậy, ở đầu nested.rs, thêm những điều sau đây: #[path = "inaccessible.rs"]và trên dòng tiếp theo:mod inaccessible;
Gardener


2
@HemanGandhi thêm mod inaccessible;vào my/mod.rsđể làm cho nó trở thành mô-đun con của my, sau đó truy cập mô-đun anh chị em từ nested.rsbằng đường dẫn tương đối super::inaccessible::function(). bạn không cần paththuộc tính ở đây.
Artin

9

Tôi thực sự thích câu trả lời của Gardener. Tôi đã sử dụng gợi ý cho các khai báo mô-đun của mình. Ai đó vui lòng gọi điện nếu có vấn đề kỹ thuật với điều này.

./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();
}

Đã phải sử dụng 'thủ thuật' này để xuất lại fnvới cùng tên với tệp nó đã ở trong đó.#[path = "./add_offer.rs"] mod _add_offer; pub use self::_add_offer::add_offer;
Arek Bal

đây phải là câu trả lời được chấp nhận imo
Homam Bahrani
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.