创建零大小结构的多种方法之间有什么区别? [英] What are the differences between the multiple ways to create zero-sized structs?

查看:40
本文介绍了创建零大小结构的多种方法之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了四种创建没有数据的 struct 的不同方法:

I found four different ways to create a struct with no data:

struct A{} // empty struct / empty braced struct

  • struct B(); // empty tuple struct
    

  • struct C(()); // unit-valued tuple struct
    

  • struct D; // unit struct
    

  • (我将任意嵌套的元组只包含()和单变量 enum 声明排除在外,因为我知道为什么不应该这样做被使用).

    (I'm leaving arbitrarily nested tuples that contain only ()s and single-variant enum declarations out of the question, as I understand why those shouldn't be used).

    这四个声明之间有什么区别?我将它们用于特定目的还是可以互换?

    What are the differences between these four declarations? Would I use them for specific purposes, or are they interchangeable?

    这本书和参考文献出奇地无助.我确实找到了此已接受的RFC( clarified_adt_kinds)之间的区别,即单元结构也声明了常量值 D ,而元组结构也声明了构造函数 B() C(_:()).但是,它没有提供关于为什么使用它的设计指南.

    The book and the reference were surprisingly unhelpful. I did find this accepted RFC (clarified_adt_kinds) which goes into the differences a bit, namely that the unit struct also declares a constant value D and that the tuple structs also declare constructors B() and C(_: ()). However it doesn't offer a design guideline on why to use which.

    我的猜测是,当我使用 pub 导出它们时,实际上可以在模块外部构造种类的方法有所不同,但是我没有找到关于此的结论性文件.

    My guess would be that when I export them with pub, there are differences in which kinds can actually be constructed outside of my module, but I found no conclusive documentation about that.

    推荐答案

    这四个定义之间只有两个功能上的区别(这是我稍后会提到的第五种可能性):

    There are only two functional differences between these four definitions (and a fifth possibility I'll mention in a minute):

    1. 语法(最明显).麦卡顿的答案更加详细.
    2. 将结构标记为 pub 时,是否其构造函数(也称为 struct 文字语法)可在其定义的模块之外使用.
    1. Syntax (the most obvious). mcarton's answer goes into more detail.
    2. When the struct is marked pub, whether its constructor (also called struct literal syntax) is usable outside the module it's defined in.

    您的唯一一个不能从当前模块外部直接构造的示例是 C .如果您尝试执行此操作,则会收到错误消息:

    The only one of your examples that is not directly constructible from outside the current module is C. If you try to do this, you will get an error:

    mod stuff {
        pub struct C(());
    }
    let _c = stuff::C(());  // error[E0603]: tuple struct `C` is private
    

    之所以会这样,是因为该字段未标记为 pub ;如果将 C 声明为 pub struct C(pub()),该错误就会消失.

    This happens because the field is not marked pub; if you declare C as pub struct C(pub ()), the error goes away.

    您没有提到的另一种可能性是给出了更具描述性的错误消息:普通结构,大小为零的非 pub 成员.

    There's another possibility you didn't mention that gives a marginally more descriptive error message: a normal struct, with a zero-sized non-pub member.

    mod stuff {
        pub struct E {
            _dummy: (),
        }
    }
    let _e = stuff::E { _dummy: () };  // error[E0451]: field `_dummy` of struct `main::stuff::E` is private
    

    (同样,您可以通过使用 pub 进行声明,使 _dummy 字段在模块外部可用.)

    (Again, you can make the _dummy field available outside of the module by declaring it with pub.)

    由于 E 的构造函数仅可在 stuff 模块内使用,因此 stuff 的时间和方式具有独占控制权E 已创建.标准库中的许多结构都利用了这一点,例如 Box (举一个明显的例子).零大小类型的工作方式完全相同;实际上,从模块定义的外部,您唯一知道不透明类型为零大小的方法是调用

    Since E's constructor is only usable inside the stuff module, stuff has exclusive control over when and how values of E are created. Many structs in the standard library take advantage of this, like Box (to take an obvious example). Zero-sized types work in exactly the same way; in fact, from outside the module it's defined in, the only way you would know that an opaque type is zero-sized is by calling mem::size_of.

    这篇关于创建零大小结构的多种方法之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆