我发现了四种不同的方法来创建struct
没有数据:
struct A{} // empty struct / empty braced struct
struct B(); // empty tuple struct
struct C(()); // unit-valued tuple struct
struct D; // unit struct
(我留下任意嵌套的元组,其中仅包含()
s 和单变体enum
声明是不可能的,因为我理解为什么不应该使用这些声明)。
有什么区别这四个声明之间?我会将它们用于特定目的,还是可以互换?
令人惊讶的是,这本书和参考资料毫无帮助。我确实找到了这个接受的 RFC (clarified_adt_kinds) https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md这有点不同,即单位结构也声明了一个常量值D
并且元组结构还声明构造函数B()
and C(_: ())
。然而,它没有提供关于为什么使用哪个的设计指南。
我的猜测是,当我导出它们时pub
,在我的模块之外实际上可以构建哪些类型存在差异,但我没有找到关于这一点的结论性文档。
这四个定义之间只有两个功能差异(我稍后会提到第五种可能性):
- 语法(最明显的)。麦卡顿的回答 https://stackoverflow.com/a/50170328/3650362更详细的内容。
- 当结构体被标记时
pub
,无论是构造函数 https://doc.rust-lang.org/nomicon/constructors.html(也叫struct字面语法 http://words.steveklabnik.com/structure-literals-vs-constructors-in-rust) 可在其定义的模块外部使用。
唯一不能从当前模块外部直接构造的示例是C
。如果您尝试这样做,您将收到错误消息:
mod stuff {
pub struct C(());
}
let _c = stuff::C(()); // error[E0603]: tuple struct `C` is private
发生这种情况是因为该字段未标记pub
;如果你声明C
as pub struct C(pub ())
,错误消失。
您没有提到的另一种可能性会给出稍微更具描述性的错误消息:一个正常的结构,具有零大小的非pub
member.
mod stuff {
pub struct E {
_dummy: (),
}
}
let _e = stuff::E { _dummy: () }; // error[E0451]: field `_dummy` of struct `main::stuff::E` is private
(同样,您可以使_dummy
通过声明它在模块外部可用的字段pub
.)
Since E
的构造函数只能在stuff
模块,stuff
对何时以及如何值具有独家控制权E
被创建。标准库中的许多结构都利用了这一点,例如Box
(举一个明显的例子)。零大小类型的工作方式完全相同;事实上,从定义它的模块外部,您知道不透明类型为零大小的唯一方法是调用mem::size_of https://doc.rust-lang.org/std/mem/fn.size_of.html.
See also
- 创建无法在其板条箱外部实例化的零大小结构的惯用方法是什么? https://stackoverflow.com/q/64651511/3650362
- 为什么要定义一个具有单位类型的单个私有字段的结构体? https://stackoverflow.com/q/63338208/3650362
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)