我在公共公关中遇到了一个有趣的变化。最初他们有:
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub struct ParseError(ParseErrorKind);
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
enum ParseErrorKind {
OutOfRange // ... omitting other values here to be short
}
Run Code Online (Sandbox Code Playgroud)
ParseError
由于是私有的,因此无法由客户端实例化ParseErrorKind
。他们现在正在公开这一点enum
,这似乎没问题,但我建议了一种替代方案:成为ParseError
一个enum
自身,并利用类型系统,而不是用“种类”的概念来模仿它。他们告诉我这会导致 API 损坏,因此不行。
我想我明白为什么理论上 astruct
和 anenum
是不同的。但我不确定为什么它在这种情况下不兼容。
由于struct ParseError
没有可变字段并且无法由客户端实例化,因此我们无法对该类型执行任何操作,只能对其进行分配和比较。似乎两者struct
都enum
支持这一点,因此客户端代码不太可能需要更改才能使用公开的新版本enum
而不是struct
. 或者我是否错过了我们可以使用 的另一种用途struct
,这将导致需要更改客户端代码?
但是,也可能存在 ABI 不兼容的情况。Rust 在实践中如何处理struct
,因为知道只有库才能构造它?是否有任何类型的分配或释放机制需要ParseError
在构建时准确地知道它是由什么组成的?从那个确切的转换struct
到enum
那个会产生影响吗?或者在这种特殊情况下它是否安全?由于到目前为止还无法保证,这与尝试维持 ABI 相关吗?
这是因为 everystruct
都有字段,因此此模式适用于 any struct
,但不会使用以下命令进行编译enum
:
struct Foo {}
fn returns_a_foo() -> Foo {
// anything that may return a Foo
}
if let Foo { .. } = returns_a_foo() {}
Run Code Online (Sandbox Code Playgroud)
例如,此代码编译:
fn main() {
if let String { .. } = String::new() {}
}
Run Code Online (Sandbox Code Playgroud)
游乐场。
虽然可能不是您自己编写的代码,但仍然可以编写,并且还可以通过宏生成。请注意,这显然与enum
模式匹配不兼容:
if let Option { .. } = None {
// Compile error.
}
Run Code Online (Sandbox Code Playgroud)
游乐场。
归档时间: |
|
查看次数: |
97 次 |
最近记录: |