如何限制struct的构造? [英] How to restrict the construction of struct?

查看:47
本文介绍了如何限制struct的构造?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to forbid creating an instances directly from member initialization?

例如

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")} 来创建实例.有没有办法避免这种情况?

I can still use Person {age: 6, name:String::from("mike")} to create instance. Is there anyway to avoid this?

推荐答案

不,您不能从成员初始化创建该结构,因此您的问题已经是答案.

No, you cannot create that struct from member initialization and therefore your question is already the answer.

这是因为成员默认是私有的,不能直接使用.只有直接模块及其子模块可以访问私有字段、函数、...(参见 关于可见性的书).

This is because members are by default private and cannot be used directly. Only the immediate module and its submodules can access private fields, functions, ... (see 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关键字.

On the other hand, if you want to make it possible to create an instance by member initialization, use the pub keyword in front of all members.

pub struct Person {
    pub name: String,
    pub age: u8,
}

有时让您的 crate 用户直接访问成员很有用,但您希望将实例的创建限制为您的构造函数".只需添加一个私有字段.

Sometimes it's useful to let the user of your crate access the members directly, but you want to restrict the creation of an instance to your "constructors". Just add a private field.

pub struct Person {
    pub name: String,
    pub age: u8,
    _private: ()
}

因为不能访问_private,所以不能直接创建Person的实例.

Because you cannot access _private, you cannot create an instance of Person directly.

还有 _private 字段阻止通过 更新语法,所以这失败了:

Also the _private field prevents creating a struct via the update syntax, so this fails:

/// same code from above

fn main() {
    let p = Person::new(8, String::from("Peter"));
    let p2 = Person { age: 10, ..p };
}

error[E0451]: field `_private` of struct `foo::Person` is private
  --> src/main.rs:27:34
   |
27 |     let p2 = Person { age: 10, ..p };
   |                                  ^ field `_private` is private

这篇关于如何限制struct的构造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆