为什么Rust没有工会?

unn*_*ddr 27 rust

我可以想到许多地方,C帮助中的工会是有用的,它们可以节省记忆.由于Rust是一种系统编程语言,为什么它不支持工会呢?

Man*_*rse 50

工会被添加到(RFC 1444)中的语言中,从Rust 1.19.0开始它们是稳定的.他们需要使用unsafe块.

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

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

  • @ReinF,尽管在实践中我希望额外的字节通常会被填充到机器字大小以提高效率。 (12认同)
  • “以换取少量的内存使用”,我只是想补充一点,这个额外的内存只是标识符,它是 1 个字节(只要不超过 256 个变体)。 (2认同)

Chr*_*gan 27

Rust 以其代数数据类型的形式标记了联合enum:

enum Foo {
    Bar(i32),
    Baz,
    Quux {
        misc: A,
        ellaneous: B,
        fields: C,
    },
}
Run Code Online (Sandbox Code Playgroud)

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


什么锈也不会拥有的是未标记工会为C.为什么?因为它们基本上是不安全的,安全对Rust来说至关重要.如果你仍然想要这样的东西,很有可能围绕不安全的代码创建一个包装器,你将会遇到嬗变发生的事情,但你在正常生活中根本不需要未标记的联合.

现在支持无标记工会作为一个不安全的概念; 截至1.19.0.

  • 即使你只有两个变量(例如`enum X {S(i32),U(u32)}`是8个字节),标签也可能大于一个字节,因为对齐.从技术上讲,它是一个带有三个字节填充的字节,但最终结果是相同的. (3认同)