是否可以声明一个元组结构,其成员是私有的,除了初始化?

Is it possible to declare a tuple struct whose members are private, except for initialization?

是否可以声明一个元组结构,其中除了声明之外的所有意图和目的都是隐藏成员的?

// usize isn't public since I don't want users to manipulate it directly
struct MyStruct(usize); 

// But now I can't initialize the struct using an argument to it.
let my_var = MyStruct(0xff)
//                    ^^^^
//                    How to make this work?

有没有办法让成员保持私有,但仍允许使用如上所示的参数初始化新结构?

作为替代方案,可以实现 MyStruct::new 之类的方法,但我仍然想知道是否可以避免在该类型上使用方法,因为它更短,而且对包装单个变量的类型。


背景

不谈太多细节,这个类型的唯一目的是包装一个单一的类型(隐藏一些细节,添加一些功能并在编译时完全优化的助手),在这种情况下,它并没有完全暴露隐藏的内部结构以使用 Struct(value) 样式初始化。 此外,由于包装器的开销为零,因此使用通常与 allocation/creation 关联的 new 方法而不是强制转换有点误导。

因为方便输入 (int)vint(v),而不是 int::new(v),我想为我自己的类型做这个。

经常使用,所以使用短表达式的能力非常方便。目前我正在使用一个调用 new 方法的宏,它可以,但有点 awkward/indirect,因此这个问题。

恐怕这样的概念是不可能的,但这是有充分理由的。结构的每个成员,除非用 pub 标记,都被认为是一个实现细节,不应该出现在 public API 的表面,无论对象当前何时以及如何正在使用。从这个角度来看,问题的目标变成了一个难题:希望保持成员私有,同时让 API 用户任意定义它们不仅不常见,而且不是很明智。

如您所述,推荐使用名为 new 的方法。这并不是说您要通过必须键入的额外字符来损害代码的可读性。或者,对于已知结构环绕项目的情况,使成员 public 可能是一种可能的解决方案。另一方面,这将允许通过可变借用进行任何类型的突变(因此可能会破坏结构的不变量,如@MatthieuM 所述)。这个决定取决于预期的 API.

严格来说这在 Rust 中是不可能的。

然而,使用具有类似名称的函数 的普通 struct 可以实现预期的结果(是的,这有效!)

pub struct MyStruct {
    value: usize,
}

#[allow(non_snake_case)]
pub fn MyStruct(value: usize) -> MyStruct {
    MyStruct { value }
}

现在,您可以编写 MyStruct(5) 但不能访问 MyStruct 的内部。