2014-10-06 22 views
23

Naprawdę nie mogę znaleźć sposobu włączenia (lub importu, wstrzyknięcia lub czegoś) z jednego pliku (modułu) do drugiego.Podstawowe importowanie rdzeni (obejmuje)

Oto przykład.

zaczynam nowy projekt z

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

Potem modyfikować main.rs i utworzyć nowy plik a.rs (wewnątrz src dir) za pomocą następującego kodu:

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


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

uruchomić projekt z cargo run

Tutaj mam dwa błędy:

  • src/main.rs: 2: 20: 2:26 błąd: nie udało się rozwiązać. Użycie niezadeklarowanego modułu a
  • src/main.rs: 2: 20: 2:26 błąd: nierozwiązana nazwa a::foo.

W tej chwili wydaje się dość oczywiste, po prostu muszę importować a jakoś.

Próbowałem dodać następujące rzeczy jako pierwsza linia do main.rs

  • use a; -> Błąd: nierozwiązana import (? Może chodziło a::*)
  • use a::*; -> Błąd: glob instrukcje importu są eksperymentalne i prawdopodobnie buggy
  • use a::foo; -> błąd: nierozstrzygnięty import a::foo. Może brakujące extern crate a?
  • extern crate a; use a::foo; -> Błąd: nie można odnaleźć skrzynię dla a
  • extern crate proj; use proj::a::foo; -> Błąd: nie można odnaleźć skrzynię dla proj

Czytałem the guide at rust-lang ale nadal nie można dowiedzieć się, jak to zrobić importu .

Odpowiedz

23

W głównym module (main.rs, lib.rs lub subdir/mod.rs), musisz napisać mod a; dla wszystkich innych modułów, których chcesz użyć w całym projekcie (lub w podkatalogu).

W każdym innym modułem, trzeba napisać use a; lub use a::foo;

Jesteś daleko od jedynej osoby, która ma być mylony przez to, i to z pewnością możliwe zrobić lepiej, ale wszelkie zmiany w systemie moduł zostać odrzuconym jako "zbyt mylące".

+1

Kiedy zatem konieczna jest skrzynka zewnętrzna? Myślałem, że każdy plik Rusta jest oddzielną skrzynką (jednostką kompilacji). – voithos

+3

@voithos Twoje main.rs lub lib.rs i wszystkie pliki rekursywnie odwracające się za pomocą instrukcji 'mod' zostaną skompilowane jako skrzynia. To jest jednostka kompilacji. – Levans

+17

'ale wszelkie zmiany w systemie modułowym zostaną odrzucone jako" zbyt mylące "' Istniejący system modułów jest "zbyt zagmatwany". – Qix

3

w Rust, istnieją pewne słowa kluczowe do czynienia z modułami:

extern crate wypełnia lukę między Cargo i Rust. Piszemy kod w pliku .rs, ten plik może być skompilowany z rustc. Cargo zarządza zewnętrznymi zależnościami i wywołuje rustc. Linia extern crate ... mówi kompilatorowi, aby szukał tego obszaru nazw, więc jest jednoznaczny.

mod ma dwa zastosowania:

  • gdy używana z klamrami deklaruje moduł (namespace).
  • w przypadku użycia tylko z nazwą, będzie szukał modułu w lokalnym systemie plików.

Moduły mogą być:

  • pliki z rozszerzeniem .RS
  • foldery z jednego pliku o nazwie mod.rs

use importuje nazw. Musimy ogłosić, co będziemy używać przed użyciem. Klauzula użycia jest dość ścisła, jeśli podamy use module1::moduleA; żaden inny moduł z module1 nie będzie dostępny, ale. Gwiazdkę (*) można użyć do użycia wszystkiego w module: use module1::*;. Zestawy mogą być również stosowane: use module1::{moduleA, moduleB};

Przykład:

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

mod.rs zawiera:

pub mod moduleA; // declare a sibling file 
pub mod moduleA; // declare a sibling file 

main.rs zawiera:

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

/// ====== 

// add my other sources to the tree: 
mod module1; 

// some local stuff 
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(); 
} 

Symbole są wyłącznie nadające z poziomu modułu. Jeśli chcesz przekroczyć tę barierę (nawet w lokalnym module deklarowanym), musimy je upublicznić, używając słowa kluczowego pub.

Powiązane problemy