#匿名 #多态 #联合 #类型 #变体

fed

稳定 Rust 中的匿名、标记联合的草图实现

9 个不稳定版本 (3 个破坏性更新)

使用旧的 Rust 2015

0.4.4 2017年9月13日
0.4.2 2017年9月13日
0.4.0 2017年8月31日
0.3.0 2017年8月10日
0.1.0 2016年12月2日

#1459Rust 模式

每月24次下载

Apache-2.0

160KB
2K SLoC

fed

用法

在您的 Cargo.toml 文件中

[dependencies]
fed = "0.4"

为了能够声明类型联合,各种 Fed* 类型需要由您的 crate 拥有。为此,声明泛型 FedX<*_> 的代码包含在一个宏中,用户需要在 crate 根目录中调用此宏

#[macro_use]
extern crate fed as fed_;
init_fed!();

这将创建一个位于 crate 根目录的 fed 模块。

由于许多功能(特别是 .into() 技巧)目前只能在具体类型上定义,您需要显式使用 fed! 宏声明类型联合

fed!(
    usize,
    bool,
    Option<String>,
    char,
);

这将实现对于具体类型 Fed4<usize, bool, Option<String>, char> 以及所有 2 型和 3 型子集的具体类型 Fed2Fed3::fed::* 中的特征。

由于 Fed1 是仅包含一个类型的联合,因此它可以有完全泛型的 ::fed::* 特征实现。

三个直接相关的限制

  1. 当使用任何生成的具体类型联合并指定联合中的类型时,类型必须按照在 fed! 调用中声明的顺序列出。在上面的例子中,Fed2<usize, bool> 现在是可用的,但 Fed2<bool, usize> 是不可用的。

  2. 由于 Rust 禁止重复的相同特征实现,第二个 fed! 声明中列出的类型不能与第一个类型联合中的类型集合有超过一个类型的共同子集(除非您以这种方式排列第二个类型联合,使得没有有序子集与第一个类型联合的有序子集相同(如第一点所述))。

  3. 不支持超过 8 个类型的类型联合。

现在,您可以创建您声明的联合中任何子集的类型集合,而无需为专用枚举想出名称

use ::fed::*;

let vec: Vec<Fed3<usize, bool, char>> = vec![
    false.into(),
    27usize.into(),
    0usize.into(),
    'A'.into(),
];

assert_eq!(vec.iter().filter(Fed::is::<usize>).count(), 2);
assert_eq!(vec[3].extract::<char>(), Ok('A'));

推导非标准特征

通过 init_fed! 宏调用声明时,类型联合结构体(Fed0Fed1,... Fed8)推导出所有内置的 #![derive(...)] 特征(例如,CopyDebug)。如果您需要额外的可推导特征(例如,serde 的 SerializeDeserialize),则使用以下语法作为 init_fed! 的特殊参数包含它们

#[macro_use]
extern crate serde_derive;

init_fed!(@deriving: [Serialize, Deserialize]);

无运行时依赖