是否可以禁止直接通过成员初始化创建实例?
例如
pub struct Person {
name: String,
age: u8,
}
impl Person {
pub fn new(age: u8, name: String) -> Person {
if age < 18 {
panic!("Can not create instance");
}
Person { age, name }
}
}
我仍然可以使用Person {age: 6, name:String::from("mike")}
创建实例。反正有避免这种情况吗?
答案 0 :(得分:5)
否,您不能通过成员初始化来创建该结构,因此您的问题已经是答案。
这是因为默认情况下成员是私有的,不能直接使用。只有立即模块及其子模块可以访问私有字段,函数...(请参见the book about visibility)。
mod foo {
pub struct Person {
name: String,
age: u8,
}
impl Person {
pub fn new(age: u8, name: String) -> Person {
if age < 18 {
panic!("Can not create instance");
}
Person { age, name }
}
}
}
use foo::Person; // imagine foo is an external crate
fn main() {
let p = Person {
name: String::from("Peter"),
age: 8,
};
}
error[E0451]: field `name` of struct `Foo::Person` is private
error[E0451]: field `age` of struct `Foo::Person` is private
另一方面,如果要使通过成员初始化创建实例成为可能,请在所有成员前面使用pub
关键字。
pub struct Person {
pub name: String,
pub age: u8,
}
有时候让板条箱的用户直接访问成员很有用,但是您希望将实例的创建限制为“构造函数”。只需添加一个私有字段即可。
pub struct Person {
pub name: String,
pub age: u8,
_private: ()
}
由于无法访问_private
,因此无法直接创建Person
的实例。