许多人看着Coroutines TS,不知道,这些大惊小怪的是什么?
本文为您提供了一个激励性的示例,在该示例中,惰性序列使您能够分开关注点,并在不增加复杂性的情况下最大化代码重用。
示例:近似黄金分割率
每个数学专业的学生都知道如何通过斐波那契数列来近似黄金分割率:
fib(n+1) / fib(n) -> φ = 1.6180…
或使用C ++…
函数golden
计算给定近似值的黄金比例。 在每次迭代中,我们都接近黄金分割率,并且一旦我们足够接近,函数就会返回。
这很简单,但是如果我们还有一些golden
用例呢?
- 也许我们想限制最大迭代次数
- 或者也许我们想在每次迭代后打印
- 或者,也许我们想返回一个
{ fib(n+1), fib(n) }
的元组 - 也许有一个我们尚未想到的用例,但有人可能会下定决心
为了满足所有这些要求,我们需要修改算法并提供一些定制点。 我们可以添加一组配置选项,或者使用通用函数:
我们可以看到,随着我们将其通用化以处理更多用例,此功能的复杂性也在增加。 这个版本的golden
比原始版本的可读性差得多!
一种替代方法是针对每个特定用例编写此函数的变体。 这是一个打印每次迭代的版本:
这是可读的,但现在我们必须维护多个功能!
我们如何实现可重用性和简单性?
这是问题所在。 模板化版本很灵活,但并不简单。 函数变体很简单,但不灵活。 我们如何实现可重用性和简单性?
为什么我们必须在它们之间进行选择?
此问题是由以下事实引起的:算法控制序列的迭代和序列的 表示 。 这些关注点应该分开。
那么,我们需要什么样的抽象才能使两者兼得?
通过协程TS进行控制反转
Coroutines TS使您可以定义延迟序列。 惰性序列只是一组有序的值,其中每个值仅根据请求进行计算。
您可能会认为惰性序列是具有两个属性的容器:
-
bool hasNext()
这个序列中是否还有另一个值? -
T takeNext()
返回序列中的下一个值,并前进1。
结果,我们能够分离计算和表示,同时保持对序列的完全控制。
Coroutine TS的级别很低,因此以下示例是使用我们的Conduit库构建的。 该库为我们提供了各种可用于创建延迟序列的原语。 我们不会在这里详细介绍实现细节( GitHub上有完整的源代码 ),而是看一下所有这些的用处!
好。 因此,使用导管,我们可以为斐波那契定义一个惰性序列:
由于黄金比率是斐波那契数的变换,因此我们可以使用scan
来计算它们:
在这里,我们使用序列来打印前10个斐波那契比率:
现在我们有了一个可迭代的对象,我们可以像以前一样通过计算增量来控制迭代:
这样做的好处是我们只能对序列进行一个定义,但可以在多个地方使用它。 与我们之前看到的模板化解决方案不同,该代码仍然紧密地映射到数学定义。
如果您想知道如何使用Coroutine TS实施延迟序列,
签出我们的GitHub 。
结论
Coroutines TS使我们能够将控制权交还给算法使用者。 这使实现者无需向最终用户提供定制钩子来修改算法的行为。
既然你在这里...
我们最近发布了BuildInfer ,这是一种用于优化C / C ++构建脚本的新工具。 看一看 !
你也可能对此有兴趣…
From: https://hackernoon.com/c-coroutine-ts-its-about-inversion-of-control-d1588c4c4c31