xeh*_*puk 2 validation struct rust
我正在通过示例研究Rust。我目前在TryFrom和TryInto。这是他们的代码:
struct EvenNumber(i32);
impl TryFrom<i32> for EvenNumber {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value % 2 == 0 {
Ok(EvenNumber(value))
} else {
Err(())
}
}
}
Run Code Online (Sandbox Code Playgroud)
该实现防止创建EvenNumber具有奇数的实例,但前提是我调用try_from(或try_into)。我仍然可以EvenNumber(1337)直接创建一个。
在 Java(和相关语言)中,可以验证构造函数内的实例创建,例如:
struct EvenNumber(i32);
impl TryFrom<i32> for EvenNumber {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value % 2 == 0 {
Ok(EvenNumber(value))
} else {
Err(())
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何在 Rust 中做到这一点?
您将EvenNumber在某个模块内定义并保持其num字段私有,因此人们可以创建实例的唯一方法EvenNumber是通过您控制的公共方法,例如new. 例子:
mod some_mod {
pub struct EvenNumber {
num: i32,
}
impl EvenNumber {
pub fn new(num: i32) -> Result<Self, ()> {
if num % 2 == 0 {
Ok(EvenNumber {
num,
})
} else {
Err(())
}
}
}
}
// bring EvenNumber into scope
use some_mod::EvenNumber;
fn try_to_create_invalid_even_number() -> EvenNumber {
EvenNumber {
num: 1337, // compile error
}
}
Run Code Online (Sandbox Code Playgroud)
抛出:
error[E0451]: field `num` of struct `EvenNumber` is private
--> src/lib.rs:24:9
|
24 | num: 1337,
| ^^^^^^^^^ private field
Run Code Online (Sandbox Code Playgroud)
当您的元组结构体在不同的模块(可以只是不同的文件)中定义时或如下所示:
mod mod_name {
#[derive(Debug)]
pub struct EvenNumber(i32);
use std::convert::TryFrom;
impl TryFrom<i32> for EvenNumber {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
if value % 2 == 0 {
Ok(EvenNumber(value))
} else {
Err(())
}
}
}
}
fn main() {
// let num = mod_name::EvenNumber(5); // error[E0603]: tuple struct constructor `EvenNumber` is private
use std::convert::TryFrom;
let num = mod_name::EvenNumber::try_from(4);
println!("num = {:?}", num.unwrap());
}
Run Code Online (Sandbox Code Playgroud)
那么您将无法直接使用任何数字构造该元组。您可以通过取消注释上面示例中的注释行来测试这一点。在 Rust 中,实体的隐私仅对同级或父模块重要,但对相同作用域或子模块无关。