是否可以直接从成员初始化中禁止创建实例?
例如
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 }
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然可以Person {age: 6, name:String::from("mike")}用来创建实例.反正有没有避免这个?
小智 21
对于 Rust >= 1.40.0,请考虑将non_exhaustive属性应用于您的结构。
// Callers from outside my crate can't directly construct me
// or exhaustively match on my fields!
#[non_exhaustive]
pub struct Settings {
pub smarf: i32,
pub narf: i32,
}
Run Code Online (Sandbox Code Playgroud)
更多信息请参见 1.40.0发行说明。
不,您无法从成员初始化创建该结构,因此您的问题已经是答案.
这是因为默认情况下,成员是私有的,不能直接使用.只有直接模块及其子模块才能访问私有字段,函数......(请参阅有关可见性的书籍).
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,
};
}
Run Code Online (Sandbox Code Playgroud)
error[E0451]: field `name` of struct `Foo::Person` is private
error[E0451]: field `age` of struct `Foo::Person` is private
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您希望通过成员初始化创建实例,请pub在所有成员前面使用关键字.
pub struct Person {
pub name: String,
pub age: u8,
}
Run Code Online (Sandbox Code Playgroud)
有时让您的包的用户直接访问成员是有用的,但您希望将实例的创建限制为"构造函数".只需添加一个私有字段.
pub struct Person {
pub name: String,
pub age: u8,
_private: ()
}
Run Code Online (Sandbox Code Playgroud)
由于无法访问_private,因此无法Person直接创建实例.