是否可以声明一个元组结构,其中成员被隐藏用于所有意图和目的,除了声明?
// 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)
样式初始化。
此外,由于包装器开销为零,因此使用new
方法有点误导,这种方法通常与分配/创建相关而不是转换。
正如它的方便类型(int)v
或int(v)
,而不是int::new(v)
,我想为自己的类型执行此操作。
它经常使用,因此使用短表达的能力非常方便。目前我正在使用一个调用new
方法的宏,它可以但有点尴尬/间接,因此这个问题。
答案 0 :(得分:4)
严格来说,这在Rust中是不可能的。
然而,使用具有相同名称的函数的正常struct
可以实现期望的结果(是的,这有效!)
pub struct MyStruct {
value: usize,
}
#[allow(non_snake_case)]
pub fn MyStruct(value: usize) -> MyStruct {
MyStruct { value: value }
}
现在,您可以撰写MyStruct(5)
但不能访问MyStruct
的内部。
答案 1 :(得分:2)
我担心这样的概念是不可能的,但这是有充分理由的。除非标记为pub
,否则结构的每个成员都被视为不应提升到公共API表面的实现细节,无论对象当前何时以及如何使用。在这种观点下,问题的目标达到了一个难题:希望保持成员私密,同时让API用户任意定义它们不仅不常见,而且也不是很明智。
正如您所提到的,建议使用名为new
的方法。这并不是说你要用你需要输入的额外字符来破坏代码的可读性。或者,对于已知结构环绕项目的情况,使成员公开可能是一种可能的解决方案。另一方面,通过可变借用允许任何类型的突变(因此可能破坏结构的不变量,如@MatthieuM所述)。此决定取决于预期的API。