转载

如何写懒惰的代码

懒和勤奋:“懒”是一个很广泛的词,在程序员的世界里,它指只做需要做的工作。而“勤奋”在这里指做很多的工作为了未来。

考虑下面这段 JavaScript 的代码:

如何写懒惰的代码

现在的问题是: JavaScript 是否计算 2+3 ? 答案大概是:是的。当 JaveScript 在给一个函数传送参数的时候,它是非常勤奋的。它计算所有表达式,并且不管是否真的需要计算这些表达式。

如果你需要代码变得懒一些,你需要绕过它的勤奋。比如:

如何写懒惰的代码

JavaScript 会计算函数 () => 2 + 3但它不会计算函数里面的表达式。当这个函数并没有开始执行,里面的2+3并不会 被计算。

把表达式放在函数里来延迟它被计算是一个编程里经常用到的方法。有很多这方面有趣的应用。

制造懒惰

if 条件,和许多 control flow 的语句都是很懒的,他们是不会被计算直到程序真的跑到了它们的条件里。看看这段代码:

如何写懒惰的代码

想象一个 List 从1到一亿,然后我们启动这段代码:

如何写懒惰的代码

我们会得到正确的答案,但是代码先做了一个从一到一亿的 list。这样的代码太差了。因为连小孩都知道你可以随时从函数里 return 出来,然后剩下的值就被忽略不计了。所以我们可以这样写:

如何写懒惰的代码

这个版本的函数要比之前那个懒多了。根据 containing,我们可以写一个类似的函数,findwith:

如何写懒惰的代码

findwith 函数预测第一个值是不是想要的。可惜的是,虽然 findwith 是懒惰的,它却很勤奋的计算它的参数。比如说我们需要找到 list 里的第一个大于99并且顺逆序一样的数字:

如何写懒惰的代码

我们得到的结果是101。但是 JavaScript 会很勤奋地计算所有的参数,所以它计算 isPalindromic, gt(99)),还有 billion。billion 里有一亿个数,所以这样的代码太贵了。我们需要更懒的函数:

如何写懒惰的代码

现在JavaScript还是会计算 Numbers(),但是这里是一个 iterator,而不是一个 array,条件句:for (const element of list) { ... },从 iterator里取值,而不是从一个有一亿个值得 array里。

原文链接:http://raganwald.com/2016/04/15/laziness-is-a-virtue.html

原文  https://segmentfault.com/a/1190000004959407
正文到此结束
Loading...