如何限制结构的构建?

时间:2018-12-03 06:52:12

标签: rust

是否可以禁止直接通过成员初始化创建实例?

例如

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")}创建实例。反正有避免这种情况吗?

1 个答案:

答案 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的实例。