Hoe voeg je een module uit een ander bestand van hetzelfde project toe?

Door deze handleidingte volgen die ik heb gemaakt een vrachtproject.

src/main.rs

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

die ik gebruik

cargo build && cargo run

en het compileert zonder fouten. Nu probeer ik de hoofdmodule in tweeën te splitsen, maar ik kan er niet achter komen hoe ik een module uit een ander bestand moet opnemen.

Mijn projectboom ziet er zo uit

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

en de inhoud van de bestanden:

src/main.rs

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

src/hello.rs

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

Als ik het compileer met cargo buildkrijg ik

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

Ik heb geprobeerd de suggesties van de compiler op te volgen en heb main.rsgewijzigd in:

#![feature(globs)]
extern crate hello;
use hello::*;
fn main() {
    hello::print_hello();
}

Maar dit helpt nog steeds niet veel, nu snap ik dit:

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

Is er een triviaal voorbeeld van hoe een module van het huidige project in het hoofdbestand van het project kan worden opgenomen?


Antwoord 1, autoriteit 100%

Je hebt de mod helloin je hello.rs-bestand niet nodig. Code in elk bestand, behalve de hoofdmap van het krat (main.rsvoor uitvoerbare bestanden, lib.rsvoor bibliotheken) wordt automatisch op naam geplaatst in een module.

Om de code van hello.rsin je main.rsop te nemen, gebruik je mod hello;. Het wordt uitgebreid tot de code die in hello.rsstaat (precies zoals je eerder had). Uw bestandsstructuur blijft hetzelfde en uw code moet enigszins worden gewijzigd:

main.rs:

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

hello.rs:

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

Antwoord 2, autoriteit 18%

Als u geneste modules wilt hebben…

Roest 2018

Het is niet langer vereistom het bestand mod.rste hebben (hoewel het nog steeds wordt ondersteund). Het idiomatische alternatief is om het bestand de naam van de module te geven:

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

Rust 2015

Je moet een bestand mod.rsin je map plaatsen met dezelfde naam als je module. Rust by examplelegt het beter uit.

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

Antwoord 3, autoriteit 9%

Ik vind de reactie van Gardener erg leuk. Ik heb de suggestie gebruikt voor mijn moduleverklaringen. Laat iemand weten als er een technisch probleem is hiermee.

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

Antwoord 4

In een niet-main.rs (of lib.rs) bestand als je wilt opnemen uit een bestand in dezelfde map, dan werkt de onderstaande code. De sleutel is om het woord super::te gebruiken voor de include. (Zo herschrijf ik het antwoord van @rodo zonder pathte gebruiken)

Mappenstructuur:

src
├── main.rs
├── my.rs
└── my
    ├── a.rs
    └── b.rs 

A.rs opnemen in b.rs:

src/my/a.rs:

pub fn function() {
    println!("src/my/a.rs/function()");
}

src/my/b.rs:

use super::b::function;
fn f2() {
    function();
}

src/my.rs:

mod a;
mod b;

src/main.rs:

mod my;

Other episodes