- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在this question ,出现了一个问题,可以通过将使用泛型类型参数的尝试更改为关联类型来解决。这引发了一个问题“为什么关联类型在这里更合适?”,这让我想了解更多。
RFC that introduced associated types说:
This RFC clarifies trait matching by:
- Treating all trait type parameters as input types, and
- Providing associated types, which are output types.
RFC 使用图形结构作为激励示例,这也用于 the documentation ,但我承认并没有完全理解关联类型版本相对于类型参数化版本的好处。最主要的是 distance
方法不需要关心 Edge
类型。这很好,但似乎根本就没有关联类型的原因。
我发现关联类型在实践中使用起来非常直观,但我发现自己在决定何时何地在我自己的 API 中使用它们时遇到困难。
编写代码时,什么时候应该选择关联类型而不是泛型类型参数,什么时候应该相反?
最佳答案
现在在 the second edition of The Rust Programming Language 中提到了这一点.但是,让我们深入了解一下。
让我们从一个更简单的例子开始。
When is it appropriate to use a trait method?
有多种方法可以提供后期绑定(bind):
trait MyTrait {
fn hello_word(&self) -> String;
}
或者:
struct MyTrait<T> {
t: T,
hello_world: fn(&T) -> String,
}
impl<T> MyTrait<T> {
fn new(t: T, hello_world: fn(&T) -> String) -> MyTrait<T>;
fn hello_world(&self) -> String {
(self.hello_world)(self.t)
}
}
不管任何实现/性能策略,上面的两个摘录都允许用户以动态方式指定如何 hello_world
应该行为。
一个区别(语义上)是 trait
实现保证对于给定类型 T
实现trait
, hello_world
将始终具有相同的行为,而 struct
实现允许在每个实例的基础上有不同的行为。
使用方法是否合适取决于用例!
When is it appropriate to use an associated type?
类似于 trait
上面的方法,关联类型是后期绑定(bind)的一种形式(尽管它发生在编译时),允许 trait
的用户为给定实例指定要替换的类型。这不是唯一的方法(因此是问题):
trait MyTrait {
type Return;
fn hello_world(&self) -> Self::Return;
}
或者:
trait MyTrait<Return> {
fn hello_world(&Self) -> Return;
}
等价于上面方法的后期绑定(bind):
Self
有一个 Return
关联MyTrait
对于 Self
对于多个 Return
哪种形式更合适取决于强制单一性是否有意义。例如:
Deref
使用关联类型,因为如果没有唯一性,编译器会在推理过程中发疯Add
使用关联类型是因为它的作者认为给定两个参数会有一个逻辑返回类型如您所见,Deref
是一个明显的用例(技术约束),Add
的情况不太明确:也许对 i32 + i32
有意义产生 i32
或 Complex<i32>
取决于上下文?尽管如此,作者还是进行了判断,认为没有必要为添加重载返回类型。
我个人的立场是没有正确答案。尽管如此,除了单一性参数之外,我还要提到关联类型使使用特征更容易,因为它们减少了必须指定的参数数量,所以如果使用常规特征参数的灵 active 的好处不明显,我建议从关联类型开始。
关于types - 什么时候使用关联类型与泛型类型比较合适?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32059370/
我是一名优秀的程序员,十分优秀!