2015-03-25 75 views

回答

29

将联盟添加到(RFC 1444)中的语言中,并且从Rust 1.19.0开始稳定。他们需要使用unsafe块。

原始联合不是内存安全的(因为编译器无法保证始终从联合中读取正确类型(即最近写入的类型))。 Rust的目标之一是创建一个具有记忆安全性的低级语言;由于工会与此目标不兼容,因此他们未包含在Rust 1.0中。

相反,Rust有enums,它提供了工会的大部分优点,以换取较小的内存使用量,但由于枚举值始终跟踪其包含的特定类型,因此它们是内存安全的。

+1

实际上这是[目前制定的](https://github.com/rust-lang/rust/pull/36016),用于extern C兼容性。 – snuk182 2016-09-01 20:44:24

21

锈病已在其代数数据类型的形式标签联合enum

enum Foo { 
    Bar(i32), 
    Baz, 
    Quux { 
     misc: A, 
     ellaneous: B, 
     fields: C, 
    }, 
} 

Foo有可以是Bar具有附接的i32,一个Baz没有额外的数据或Quux与这三个杂项领域。这是一个带标记的联合 - 枚举的大小不会超过其变体中最大的变量加上标签所需的大小(通常为一个字节,但我想可能有更多的变体比适合一个字节),以及在某些情况下,它可以进行优化(如Option<&T>,其中内存地址0对于Some变体不合法,因此可以用来表示None变体),变体被压缩到该值。


锈做些什么有是未标记工会为C.为什么?因为它们基本上是不安全的,安全对于Rust来说是最重要的。如果你仍然需要类似的东西,那么完全有可能为不安全的代码创建一个包装,这些代码将随着转换发生,但在普通生活中你根本不需要未标记的联合。

现在支持未标记的工会作为一个不安全的概念; as of 1.19.0

+3

即使您只有两个变体(例如'enum X {S(i32),U(u32)}'是八个字节),由于对齐,该标记可以大于一个字节。从技术上讲,它是一个三字节填充字节,但最终结果是一样的。 – delnan 2015-03-25 08:26:07