2017-07-01 27 views
7

Próbuję generować liczby pierwsze. Kod musi przechowywać wszystkie wygenerowane liczby pierwsze (aby wygenerować następne), aby mieć kilka prywatnych funkcji do pomocy i jedną publiczną funkcję (generate_next_prime).Czy można ustawić prywatną zmienną w Rust?

W języku Java lub C++ napisałbym klasę PrimesGen, ale w Rust nie może być prywatnych zmiennych w strukturze. W Pythonie prawdopodobnie napisałbym moduł PrimesGen, ale w modułach Rust nie można mieć zmiennych.

Ten kod kompiluje i uruchamia:

struct PrimesGen { 
    primes_so_far: Vec<i32>, 
    next_candidate: i32, 
} 

impl PrimesGen { 
    pub fn new() -> PrimesGen { 
     PrimesGen { 
      primes_so_far: vec![], 
      next_candidate: 2, 
     } 
    } 
} 

fn main() { 
    let pg: PrimesGen = PrimesGen::new(); 
    println!("{}", pg.next_candidate); 
} 

Więc co mam zrobić?

+1

pól w struct są prywatne domyślnie. –

+0

@ FrancisGagné Dodałem mój kod, co robię źle? – Neo

+0

Jesteś w tym samym pliku, który zdefiniował 'PrimesGen', więc możesz robić z nim, co chcesz, ponieważ jesteś jego właścicielem. – loganfsmyth

Odpowiedz

9

W Rust plik jest domyślnie modułem. Po umieszczeniu kodu w pliku foo.rs, jeśli chcesz użyć tego kodu, musisz wpisać mod foo;, ponieważ nazwa tego pliku jest niejawnie nazwą modułu. Plik główny nie jest wyjątkiem: jest to jeden moduł (moduł podstawowy).

Teraz, wewnątrz modułu, wszystko ma dostęp do wszystkiego. Zobacz ten mały przykład, aby się przekonać:

struct Foo { 
    x: i32, // private 
} 

struct Bar {} 

impl Bar { 
    fn foo(f: Foo) { 
     let _ = f.x; 
    } 
} 

fn main() { 
    let f = Foo { x: 42 }; 
    Bar::foo(f); 
} 

Bar mogą uzyskać dostęp do prywatnych użytkowników z Foo: Rust, widoczność działa przez moduł, a nie struct. Wewnątrz tego samego modułu nie możesz zrobić czegoś prywatnego w stosunku do tego samego modułu.

Tak więc, jeśli chcesz, aby zmienna prywatna w swojej przykład umieścić struct i wdrożenia wewnątrz modułu:

mod prime { 
    pub struct PrimesGen { 
     primes_so_far: Vec<i32>, 
     next_candidate: i32, 
    } 

    impl PrimesGen { 
     pub fn new() -> PrimesGen { 
      PrimesGen { 
       primes_so_far: vec![], 
       next_candidate: 2, 
      } 
     } 
    } 
} 

fn main() { 
    use prime::*; 

    let pg: PrimesGen = PrimesGen::new(); 
    println!("{}", pg.next_candidate); // error: field is private 
} 
+1

Odpowiedź brzmi: nie ma dużych plików. Uroczy. – Squirrel

+2

@Squirrel Nie wiem, jak interpretować twój komentarz. Nie * masz * używać małych modułów (myślę, że chciałeś napisać "moduł"), ale jest to bardzo dobra praktyka, aby moduły były proste. – Boiethios