何时在类似单元的结构上使用零变体枚举

ITC*_*hap 5 enums struct types rust

如果我理解正确的话,rust 类似单元的结构可以像Erlang 中的原子一样使用。

但我不明白零变体枚举提供什么。有人可以解释零变体枚举的主要目的是什么,在什么情况下它们可能比类似单元的结构更受青睐?

Cha*_*man 3

零变体枚举的一种用法是表达无法访问的代码。例如,绝对正确的TryFromFromStr. 使用泛型时通常会发生这种情况。这是一个示例:OnceCell同时具有get_or_init()get_or_try_init()方法。

enum Void {}
match self.get_or_try_init(|| Ok::<T, Void>(f())) {
    Ok(val) => val,
    Err(void) => match void {},
}

Run Code Online (Sandbox Code Playgroud)

为了节省代码重复,get_or_init()方法调用get_or_try_init(). Err但是,如果不使用空枚举,这会在运行时产生成本,因为如果get_or_try_init()调用未内联,则会出现不可能的情况的恐慌)。一旦稳定下来,就会被never 类型所取代。与单元结构相比,使用空枚举有两个优点:

  1. 它们不能被错误地构建。
  2. 他们可以提示优化器此代码无法访问并允许其将其删除。它们还可以帮助开发人员避免代码中的恐慌,因为可靠的枚举可能会被转换为 never 类型match value {},并且 never 类型可能会被强制转换为任何其他类型。上面的代码中有一个例子once_cell

另一种用法是在泛型中,当您只需要类型而不是值时,例如在编译时的策略模式中,有些人更喜欢零变体枚举来表示这种类型不应该被实例化。