为什么 Rust 没有联合?
Why does Rust not have unions?
我能想到 C 帮助中的联合有用的许多地方,它们可以节省内存。 Rust 是一种系统编程语言,为什么它不支持联合?
Rust 以其代数数据类型的形式具有 标记联合 ,enum
:
enum Foo {
Bar(i32),
Baz,
Quux {
misc: A,
ellaneous: B,
fields: C,
},
}
一个 Foo
可以有一个 Bar
和附加的 i32
,一个 Baz
没有附加数据,或者 Quux
有这三个杂项领域。这是一个带标记的联合——枚举的大小不会超过它的最大变体加上标记所需的大小(通常是一个字节,但我想可能有更多的变体而不是一个字节),并且在某些可以优化的情况下(例如 Option<&T>
,其中 0 的内存地址对于 Some
变体是不合法的,因此可以用来表示 None
变体)变体是挤进值。
Rust 没有的是未标记联合,就像在C中一样为什么?因为它们从根本上来说是不安全的,而安全对于 Rust 来说是最重要的。如果您仍然想要这样的东西,完全有可能围绕不安全代码创建一个包装器,您最终会遇到诸如转变之类的事情,但您在正常生活中根本不需要未标记的联合。
Rust 现在支持未标记的联合作为不安全的概念; as of 1.19.0.
联合已添加到 (RFC 1444), and they are stable as of Rust 1.19.0 中的语言。它们需要使用 unsafe
个块。
原始联合不是内存安全的(因为编译器无法保证您始终从联合中读取正确的类型(即最近写入的类型))。 Rust 的目标之一是创建一种具有内存安全性的低级语言;由于联合与该目标不兼容,因此它们未包含在 Rust 1.0 中。
相反,Rust 具有 enums,它提供联合的大部分优点以换取少量内存使用,但它们是内存安全的,因为枚举值始终跟踪它包含的特定类型。
我能想到 C 帮助中的联合有用的许多地方,它们可以节省内存。 Rust 是一种系统编程语言,为什么它不支持联合?
Rust 以其代数数据类型的形式具有 标记联合 ,enum
:
enum Foo {
Bar(i32),
Baz,
Quux {
misc: A,
ellaneous: B,
fields: C,
},
}
一个 Foo
可以有一个 Bar
和附加的 i32
,一个 Baz
没有附加数据,或者 Quux
有这三个杂项领域。这是一个带标记的联合——枚举的大小不会超过它的最大变体加上标记所需的大小(通常是一个字节,但我想可能有更多的变体而不是一个字节),并且在某些可以优化的情况下(例如 Option<&T>
,其中 0 的内存地址对于 Some
变体是不合法的,因此可以用来表示 None
变体)变体是挤进值。
Rust 没有的是未标记联合,就像在C中一样为什么?因为它们从根本上来说是不安全的,而安全对于 Rust 来说是最重要的。如果您仍然想要这样的东西,完全有可能围绕不安全代码创建一个包装器,您最终会遇到诸如转变之类的事情,但您在正常生活中根本不需要未标记的联合。
Rust 现在支持未标记的联合作为不安全的概念; as of 1.19.0.
联合已添加到 (RFC 1444), and they are stable as of Rust 1.19.0 中的语言。它们需要使用 unsafe
个块。
原始联合不是内存安全的(因为编译器无法保证您始终从联合中读取正确的类型(即最近写入的类型))。 Rust 的目标之一是创建一种具有内存安全性的低级语言;由于联合与该目标不兼容,因此它们未包含在 Rust 1.0 中。
相反,Rust 具有 enums,它提供联合的大部分优点以换取少量内存使用,但它们是内存安全的,因为枚举值始终跟踪它包含的特定类型。