gpt4 book ai didi

rust - 如何限制struct的构造?

转载 作者:行者123 更新时间:2023-11-29 07:47:43 25 4
gpt4 key购买 nike

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

例如

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

创建实例。有什么办法可以避免这种情况吗?

最佳答案

问题的答案

您不能从成员初始化中创建该结构,因为默认情况下成员是私有(private)的,不能直接使用。只有直接模块及其子模块可以访问私有(private)字段、函数……(参见 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,
};
}

( Playground )

error[E0451]: field `name` of struct `Person` is private
error[E0451]: field `age` of struct `Person` is private

使从外部创建结构成为可能

另一方面,如果您希望通过成员初始化来创建实例,请在所有 成员前面使用pub 关键字。

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

可以访问字段,但不能从外部创建结构

请参阅 KittenOverflows answer寻求更好的方法。

--

有时让您的 crate 用户直接访问成员是有用的,但您希望将实例的创建限制为您的“构造函数”。只需添加一个私有(private)字段。

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

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

_private 字段也阻止通过 update syntax 创建结构,所以失败了:

/// 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

关于rust - 如何限制struct的构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53588819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com