A 有一个结构体,其属性可以有不同的类型
\n#[derive(Debug, Deserialize, Serialize, Clone)]\npub struct A {\n pub foo: B |\xc2\xa0C\n}\n\n#[derive(Debug, Deserialize, Serialize, Clone)]\npub struct B {\n pub bar: usize\n}\n\n#[derive(Debug, Deserialize, Serialize, Clone)]\npub struct C {\n pub bar2: usize\n}\nRun Code Online (Sandbox Code Playgroud)\nRust 是否有可能实现类似的目标pub foo: B |\xc2\xa0C, so the type will be determined on runtime?
Mas*_*inn 10
在 Rust 中是否有可能实现类似 pub foo: B | 的功能?C,所以类型将在运行时确定?
在 Rust 中执行此操作的方法是使用枚举来存储以下项之一:
#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum A {
B(B),
C(C)
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct B {
pub bar: usize
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct C {
pub bar2: usize
}
Run Code Online (Sandbox Code Playgroud)
这里可以有A两个值之一:A::B包含type 的值(以类似于单成员元组结构的方式)或包含 type 的值。并且不应混淆:前者本质上是一个函数,而后者是一种类型。BA::CCA::BB
从枚举中获取值的最基本方法是模式匹配:
fn foo(a: A) {
match a {
A::B(b) => println!("Got a B: {:?}", b),
A::C(c) => println!("Got a C: {:?}", c)
}
}
Run Code Online (Sandbox Code Playgroud)
由于 Rust 枚举是完全标准的类型,您还可以向它们添加实用方法,这正是例如Option和Result工作的方式例如
impl A {
fn b(&self) -> Option<&B> {
if let A::B(b) = self { Some(b) } else { None }
}
fn c(&self) -> Option<&C> {
if let A::C(c) = self { Some(c) } else { None }
}
}
fn bar(a: A) {
if a.b().is_some() {
println!("Got a B!");
} else {
println!("Got a C :(");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,由于您正在推导Serialize,Deserialize因此我假设您还与外部系统(例如打字稿或其他系统)进行交互。
在这种情况下,您几乎肯定必须自定义枚举的序列化方案:serde 的默认值是外部标记,根据我的经验,这永远不是您要寻找的,因为它实际上不是其他语言倾向于用于其(正式的)的方案。或非正式的)工会。
内部标记和未标记更为常见,偶尔(罕见)会出现奇怪的相邻标记。
| 归档时间: |
|
| 查看次数: |
8260 次 |
| 最近记录: |