创建一个无法在其板条箱之外实例化的零大小结构的惯用方法是啥?

Posted

技术标签:

【中文标题】创建一个无法在其板条箱之外实例化的零大小结构的惯用方法是啥?【英文标题】:What is an idiomatic way to create a zero-sized struct that can't be instantiated outside its crate?创建一个无法在其板条箱之外实例化的零大小结构的惯用方法是什么? 【发布时间】:2021-02-15 11:05:14 【问题描述】:

我有类似的东西:

mod private 
    // My crate
    pub struct A;
    
    impl A 
        pub fn new() -> Self 
            Self
        
        // ...
    


fn main() 
    // External code
    let obj = private::A::new();
    let obj2 = private::A;

目前,A 不需要存储任何内部状态来执行我想要的操作(它只是用作枚举中的占位符),因此我将其设为零大小的结构。但是,这在未来可能会改变,所以我想防止这个箱子外的代码在不经过A::new() 的情况下实例化A(即obj2main() 中的实例化应该失败)。

基本上,我想要的效果就像我向A 添加了一个私有字段一样,但我希望它保持零大小。

目前,我正在考虑这样的事情:

pub struct A 
    empty: (),

或者这个:

pub struct A(());

但是,我不确定哪种方式最惯用。

【问题讨论】:

【参考方案1】:

对此没有既定的成语。我会使用元组结构版本:

pub struct A(());

由于该字段是私有的,因此该模块之外的任何人都不能构造A

这是使用inside the standard library:

pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());

标准库also uses the named field version:

pub struct Empty 
    _priv: (),

您可以使用任何大小为零的类型(例如零长度数组或PhantomData),但() 是最简单的。

另见:

Why define a struct with single private field of unit type? What's the Rust idiom to define a field pointing to a C opaque pointer? What are the differences between the multiple ways to create zero-sized structs?

【讨论】:

以上是关于创建一个无法在其板条箱之外实例化的零大小结构的惯用方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Rust Diesel 未构建错误使用未声明的板条箱或模块

是否可以拥有一个同时具有程序宏和逻辑的板条箱?

如何配置 SublimeLinter-contrib-rustc 以找到“活塞”板条箱?

获取不同级别的图像边缘

您如何将 PostMessage 与 windows-rs 板条箱一起使用?

全栈程序员的新玩具Rust板条箱