首页 > 解决方案 > 将关联的非可变常量数据分配给枚举变量

问题描述

注意:我的问题与此问题类似,但似乎无法解决我的用例。 枚举变体可以具有恒定的关联值吗?

问题说明

我的服务器返回一个内部映射到枚举的国家(很长的列表)(有一组提前知道的有效可能性)。

我需要一些与国家相关的数据(例如语言)。

相关数据是“恒定的”,并且出于人体工程学/性能原因,将数据“附加”到枚举变量是有意义的。

人为的例子:

我有一个语言列表和一个国家列表

#[derive(Serialize,Deserialize)
enum Language {
  English,
  Spanish,
  French,
// .. 100 more
}

#[derive(Serialize,Deserialize)
enum Country {
  USA,
  England,
  France,
  Mexico,
  Spain
// .. 100 more
}

在内部,我希望枚举将语言值与国家/地区隐式关联:

// what I want

#[derive(Serialize,Deserialize)
enum Country {
  USA(Language),
  England(Language),
  // ... more countries with associated languages...
}

  1. 创建“国家”时,我不想提供语言,而只是Country::country_name(没有语言)
  2. 序列化/反序列化时,应隐式添加语言

查看 serde.rs 文档,您可以添加一个字段属性

#[serde(default)]

或者

#[serde(default = "path")]

  1. default并非所有国家/地区都有默认语言 - 而是取决于它所包含的国家/地区变体
  2. path- 在没有国家值的情况下调用该函数,因此效果类似于default

我考虑过的一些选项

  1. 手动实现序列化/反序列化 - 但我有很多情况并且容易出错
  2. 惰性常数值?冗长的

标签: rustenumsserdeassociated-value

解决方案


不是一个理想的解决方案,但在我的用例中是合理的:

使用lazy_staticconst数据(在我的情况下,根据问题中的示例,数据不是 const'able)

impl Country {
  fn language() -> '&static Language { // my language is more complex than just a simple type described in this question so i do want to have static instances . understandably in the answer it seems overkill
     match self {
        USA => {
          lazy_static! {
             let lang: Language = Language::English; /// in reality more data here...
          }
          &lang
        }
        France => { ...}
        // ... more countries
     }
  }
}

推荐阅读