为什么使用我的类型作为外部类型合法的参数来实现外部特征?
Why is implementing an external trait using my type as a parameter for an external type legal?
我正在修改一些代码以依赖于 rand 版本 0.5。起初,我担心如何使用 Standard
生成我自己类型的随机值,但我发现这是合法的:
impl ::rand::distributions::Distribution<MyType> for ::rand::distributions::Standard {
// ...
}
为什么合法?我认为为外部类型实现外部特征是 illegal.
这些规则(称为 孤儿规则 或 连贯性规则)的全部目的是避免给定的任何冲突实现trait/type组合。自 Rust 1.0 以来,人们认为 "willy-nilly" 关于允许谁为类型实现特征
不符合追求稳固稳定性的语言。
这种特殊实现类型的一个非常常见的例子是 From
:
impl From<MyType> for i32 {
// ...
}
通过使用局部类型对特征进行参数化,对于谁在实现特征仍然没有歧义。一种思考方式是将 Distribution
视为不是特征,而是 特征构造函数 1。 Distribution
的每个实例都会创建一个新特征,一个为案例定制的特征。
另请参阅:
- RFC 2451, "Re-Rebalancing Coherence"
- RFC 1023, "Rebalancing Coherence"
- How do I implement a trait I don't own for a type I don't own?
1 — 这不是真的,但这是一个合理的类比。
我正在修改一些代码以依赖于 rand 版本 0.5。起初,我担心如何使用 Standard
生成我自己类型的随机值,但我发现这是合法的:
impl ::rand::distributions::Distribution<MyType> for ::rand::distributions::Standard {
// ...
}
为什么合法?我认为为外部类型实现外部特征是 illegal.
这些规则(称为 孤儿规则 或 连贯性规则)的全部目的是避免给定的任何冲突实现trait/type组合。自 Rust 1.0 以来,人们认为 "willy-nilly" 关于允许谁为类型实现特征
不符合追求稳固稳定性的语言。这种特殊实现类型的一个非常常见的例子是 From
:
impl From<MyType> for i32 {
// ...
}
通过使用局部类型对特征进行参数化,对于谁在实现特征仍然没有歧义。一种思考方式是将 Distribution
视为不是特征,而是 特征构造函数 1。 Distribution
的每个实例都会创建一个新特征,一个为案例定制的特征。
另请参阅:
- RFC 2451, "Re-Rebalancing Coherence"
- RFC 1023, "Rebalancing Coherence"
- How do I implement a trait I don't own for a type I don't own?
1 — 这不是真的,但这是一个合理的类比。