具有独占字段的 Rust 记录结构

问题描述 投票:0回答:1

tl;dr 如何创建具有互斥字段的 record 结构?

我有一个record结构。我正在使用

records
procmacro 让这变得更容易一些。

use ::records;

#[records::record]
pub struct MyRecord {
    a: Option<bool>,
    b: Option<i32>,
}

fn main() {
    let mr: MyRecord = MyRecord::new(/* either field might be Some(..), but not both*/);
    match mr {
        MyRecord { a: Some(_), b: None } => {},
        MyRecord { a: None, b: Some(_) } => {},
        _ => panic!("bad MyRecord!"),
    }
}

我希望

match
语句不需要
panic
或有任何其他错误处理。或者换句话说,永远不应该出现两个字段都是
MyRecord
或两个字段都是
Some(_)
None

我想做这样的事情(人为的代码):

use ::exclusive_record_struct;

#[exclusive_record_struct]
pub struct MyRecord {
    a: bool,
    b: i32,
}
fn main() {
    let mr: MyRecord = MyRecord::new(/* either field might be set, but not both*/);
    match mr {
        MyRecord { a: _ } => {},
        MyRecord { b: _ } => {},
    }
}

我将如何做与该代码类似的事情?

exclusive_record_struct
是一个虚构的 procmacro 示例。但是,它不需要是 procmacro。最重要的是拥有一个记录结构,它可以保证只设置一个字段。

我知道我可以使用

union
。但是,
union
不提供此保证,
union
也不知道哪些字段是有效的。

rust
1个回答
0
投票

在 Rust 中,您可以将数据附加到枚举的变体,如下所示:

pub enum MyRecord {
    A(pub bool),
    B(pub i32),
}

fn main() {
    let mr: MyRecord = MyRecord::A(true);
    match mr {
        MyRecord::A(a) => println!("Variant A, value: {a:?}"),
        MyRecord::B(b) => println!("Variant B, value: {b:?}"),
    }
}

参见:https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#enum-values

© www.soinside.com 2019 - 2024. All rights reserved.