「这是我参与11月更文挑战的第 6 天,活动详情查看:2021最后一次更文挑战」
现在除了我们的代码更干净一些,而且可能更有性能外,其实没有什么变化。
我们减少了运行时的开销,这很好。用户仍然不能用错误的类型创建一个连接器,因为他们必须使用new,而new()是在一个有 trait bound 的 impl block 中。
如果我们后来发现我们只在类似的 impl block 中调用 Connector::new
,我们就可以删除这个特定的 trait bound。注意,标准库使用 pub(in crate::iter)
来确保 Map::new
不会在其他地方被误用。现在让我们来谈谈 Point Vec。
这并不是标准库中的做法。这个迭代器实际上拥有这个Vec。这不仅对使用Vec类型而不是其他集合施加了不必要的限制,而且它还拥有集合本身的所有权,而不仅仅是它的内容。这是一个初步的步骤,以确保我们理解我们在做什么。标准库在iter模块中对泛型特质的使用是高超的,但很容易模仿。在我们继续创建我们想要的确切水平的灵活性之前,这一步确保我们有正确的行为。
1 | rust复制代码impl<Id, F> Iterator for Connector<Id, F> |
Traits
trait 本身就是一个类型系统的抽象。将我们自己的trait与trait约束的泛型结合起来,是掌握的一个重要步骤。
让我们从使用trait来实现Vec类型的一个方法开始。这看起来类似于在一个迭代器上调用map或filter。用一个方法来命名一个trait,这被认为是 “最佳做法”,即以该方法命名。
所以我们的单方法trait将被命名为:Connect
。这个trait将取代我们现在的 connect()
。
当我们写 impl<T, U>
时,我们是在声明哪些泛型在该 impl 块的范围内。我们必须将这些泛型作为类型参数传递到 trait 中。看一下trait,我们就知道为什么了:这些类型参数告诉编译器在trait的方法中期待什么类型。现在编译器知道我们的实现正确地使用了 connect()。
1 | rust复制代码trait Connect<Id, F> |
现在我们将完成编写我们的连接器的迭代器。
我们将通过在另一个迭代器(不仅仅是一个Vec)上调用connect来创建它。让我们对标准库中的类似类型做一些观察,并将这些观察应用到我们的代码中。
本文转载自: 掘金