在Rust中是否可以创建私有变量?

25

我想要生成质数。代码需要储存所有已生成的质数(以便生成下一个质数),并拥有一些私有函数来帮助和一个公共函数 (generate_next_prime)。

在Java或C++中,我会编写一个PrimesGen类,但是在Rust中结构体中不能有私有变量。在Python中,我可能会编写一个PrimesGen模块,但是在Rust中模块不能有变量。

这段代码可以编译并运行:

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

那么我该怎么做呢?


2
结构体中的域默认为私有。 - Francis Gagné
@FrancisGagné 我添加了我的代码,我做错了什么? - Neo
你现在在定义“PrimesGen”的同一个文件中,所以你可以随意使用它,因为你拥有它。 - loganfsmyth
@loganfsmyth,我把它移到另一个文件中了,它可以工作了,非常感谢你! - Neo
1个回答

39
在Rust中,文件隐式地是一个模块。当你将一些代码放在 foo.rs 文件中时,如果你想使用这个代码,你必须输入 mod foo;,因为这个文件的名称隐含地成为了模块的名称。与此相同的,具有main函数的文件也不例外:它是一个模块(即基本模块)。

现在,在一个模块内,每个东西都可以访问到其他所有东西。看看下面的例子就能明白:

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可以访问Foo的私有成员:在Rust中,可见性是按照模块而不是结构体来工作的。在同一个模块中,您不能将某些内容标记为私有并仅在该模块内部使用。

因此,如果您想在示例中使变量私有,请将您的结构体和实现放在一个模块内:

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
}

9
答案就是不要有大文件。可爱。 - Squirrel
11
不确定如何解释你的评论。你不必使用小型模块(我认为你想写“模块”),但保持模块简单确实是一个非常好的实践。 - Boiethios
9
@Sahsahae,你声称“复制粘贴”比函数更快速和更易于维护,这一说法很奇怪。此外,“ed”已经过时了。 - Sapphire_Brick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接