Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make a private variable in Rust?

Tags:

private

rust

I'm trying to generate prime numbers. The code needs to store all the generated primes (to generate the next), to have some private functions to help and one public function (generate_next_prime).

In Java or C++, I would write a PrimesGen class, but in Rust there can't be private variables in a struct. In Python I would probably write a PrimesGen module, but in Rust modules can't have variables.

This code compiles and runs:

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);
}

So what do I do?

like image 344
Neo Avatar asked Jul 01 '17 22:07

Neo


1 Answers

In Rust, a file is implicitly a module. When you put some code in a foo.rs file, if you want to use this code, you must type mod foo; because the name of this file is implicitly the name of the module. The file with the main is not an exception: it is one module (the base module).

Now, inside a module, everything has access to everything. See this little example to be convinced:

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 can access the private members of Foo: in Rust, the visibility works by module, and not struct. Inside a same module you cannot do something private towards the same module.

So, if you want to make the variable private in your example, put your struct and implementation inside a module:

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
}
like image 50
Boiethios Avatar answered Oct 17 '22 22:10

Boiethios