【问题标题】:Why do Enums require (store) a tag? [closed]为什么枚举需要(存储)标签? [关闭]
【发布时间】:2019-08-19 23:17:41
【问题描述】:

来自Rust-Language book,

枚举类型的值包含有关它是哪个变体的信息,以及与该变体相关的任何数据。这有时被称为“标记联合”,因为数据包含一个“标记”,指示它是什么类型。编译器使用此信息来强制您安全地访问枚举中的数据。例如,您不能简单地尝试解构一个值,就好像它是可能的变体之一:

为什么 Rust 联合需要标签?如果编译器对编译时使用的枚举类型和构造函数有足够的内部知识,为什么它必须为每个枚举值分配一个字节来内部存储“标签”?此信息是否曾在运行时使用过?其他锈类型是否存储标签?

【问题讨论】:

  • 如果你有一个Result 是一个值或一个错误,编译器怎么能提前知道它会是什么? “关于枚举类型的足够内部知识”是什么?
  • Rust 有工会,但他们没有标签。枚举根据定义有一个标签;他们被标记为工会。
  • 如果你可以用特征和泛型做到这一点,请随意!但是你不能单态化在编译时值未知的东西。这就是enum 的用途。考虑if rand::random() { Some(10) } else { None }
  • (需要明确的是,在某些情况下enum 标签可能会被优化掉——如果enum 仅用于单个函数,它会被加载到寄存器中,并且标签register 恰好永远不需要,因为不同的变体仅用于互斥、不收敛的代码路径。但我觉得这种优化不是你要问的。)
  • 在一些未指定枚举的一般情况下,编译器将不知道给定变量包含什么变体,因此需要某种方式来区分。除此之外的任何事情都是编译器优化的领域。

标签: enums rust


【解决方案1】:

虽然编译器有足够的信息来创建任何特定的枚举变体,但您可以将该变体作为参数传递给期望枚举的任何可能变体的人。当值被转移时,原始变体的知识就会丢失,特别是因为可以使用不同的变体调用相同的函数。所以,方法是使用标签。

有些语言使用 vtable 或类指针而不是标签,但这里 Rust 选择了术语“标签”——然而它并没有说标签是一个字节,所以它可以被实现作为指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-04
    • 2010-10-23
    • 1970-01-01
    • 2013-10-12
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    相关资源
    最近更新 更多