我可以想到许多C工会中的工会都很有用的地方,他们可以节省内存。由于Rust是一种系统编程语言,它为什么不支持联合?Rust为什么没有工会?
回答
将联盟添加到(RFC 1444)中的语言中,并且从Rust 1.19.0开始稳定。他们需要使用unsafe
块。
原始联合不是内存安全的(因为编译器无法保证始终从联合中读取正确类型(即最近写入的类型))。 Rust的目标之一是创建一个具有记忆安全性的低级语言;由于工会与此目标不兼容,因此他们未包含在Rust 1.0中。
相反,Rust有enums,它提供了工会的大部分优点,以换取较小的内存使用量,但由于枚举值始终跟踪其包含的特定类型,因此它们是内存安全的。
锈病已在其代数数据类型的形式标签联合,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。
即使您只有两个变体(例如'enum X {S(i32),U(u32)}'是八个字节),由于对齐,该标记可以大于一个字节。从技术上讲,它是一个三字节填充字节,但最终结果是一样的。 – delnan 2015-03-25 08:26:07
实际上这是[目前制定的](https://github.com/rust-lang/rust/pull/36016),用于extern C兼容性。 – snuk182 2016-09-01 20:44:24