简体   繁体   English

为什么Rust没有工会?

[英]Why does Rust not have unions?

I can think of many places where unions in C help are useful and they save memory. 我可以想到许多地方,C帮助中的工会是有用的,它们可以节省记忆。 As Rust is a system programming language, why doesn't it support unions? 由于Rust是一种系统编程语言,为什么它不支持工会呢?

Unions were added to the language in ( RFC 1444 ), and they are stable as of Rust 1.19.0 . 工会被添加到( RFC 1444 )中的语言中,从Rust 1.19.0开始它们是稳定的。 They require usage of unsafe blocks. 他们需要使用unsafe块。

Raw unions are not memory-safe (as there is no way for the compiler to guarantee that you always read the correct type (that is, the most recently written type) from the union). 原始联合不是内存安全的(因为编译器无法保证始终从联合中读取正确的类型(即最近编写的类型))。 One of the goals of Rust is to create a low-level language with memory safety; Rust的目标之一是创建一种具有内存安全性的低级语言; since unions are not compatible with that goal, they were not included in Rust 1.0. 由于工会与该目标不兼容,因此它们不包含在Rust 1.0中。

Instead, Rust has enums , which provide most of the advantages of unions in exchange for a small memory usage, but which are memory safe since the enumeration value always keeps track of which particular type it contains. 相反,Rust有枚举 ,它提供了联合的大部分优点,以换取小内存使用,但由于枚举值始终跟踪它包含的特定类型,因此它们是内存安全的。

Rust has tagged unions in the form of its algebraic data types, enum : Rust以其代数数据类型的形式标记了联合enum

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

A Foo there can be either a Bar with an attached i32 , a Baz with no additional data or a Quux with those three miscellaneous fields. 一个Foo可以有一个带有附加i32Bar ,一个没有附加数据的Baz或带有这三个杂项字段的Quux This is a tagged union—the size of an enum will not exceed the largest of its variants plus as much as is needed for the tag (typically one byte, but I guess it's possible to have more variants than fit in one byte), and in certain cases where it can be optimised (like Option<&T> where a memory address of 0 is not legal for the Some variant and so can be used to represent the None variant) the variant is squeezed into the value. 这是一个标记的联合 - 枚举的大小不会超过其变体的最大值加上标签所需的大小(通常是一个字节,但我想可能有更多的变体而不是一个字节),以及在某些可以优化的情况下(如Option<&T> ,其中0的内存地址对于Some变量是不合法的,因此可以用来表示None变量)变量被压缩到值中。


What Rust does not have is untagged unions as in C. Rust没有的是没有 标记的工会,就像在C. Why? 为什么? Because they're fundamentally unsafe, and safety is paramount for Rust. 因为它们基本上是不安全的,安全对Rust来说至关重要。 If you still want something like that, it's perfectly possible to create a wrapper around the unsafe code that you will wind up with with things like transmutation happening, but you simply don't need untagged unions in normal life. 如果你仍然想要这样的东西,很有可能围绕不安全的代码创建一个包装器,你将会遇到嬗变发生的事情,但你在正常生活中根本不需要未标记的联合。

Rust does now support untagged unions as an unsafe concept; 现在支持无标记工会作为一个不安全的概念; as of 1.19.0 . 截至1.19.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM