[1, 2, 3, -1, -2].filter({ $0 > 0 }).count // => 3
[1, 2, 3, -1, -2].lazy.filter({ $0 > 0 }).count // => 3
在第二个语句中添加lazy
有什么好处。根据我的理解,当使用 lazy
变量时,内存会在使用时初始化为该变量。它在这种情况下有何意义?
尝试更详细地了解 LazySequence
的使用。我曾在序列上使用过 map
、reduce
和 filter
函数,但从未在 lazy
序列上使用过。需要了解为什么要使用它?
最佳答案
lazy
改变数组的处理方式。当不使用 lazy
时,filter
处理整个数组并将结果存储到一个新数组中。当使用 lazy
时,序列或集合中的值是按需从下游函数生成的。这些值不存储在数组中;它们只在需要时生产。
考虑这个修改后的示例,我在其中使用了 reduce
而不是 count
以便我们可以打印出正在发生的事情:
不使用lazy
:
在这种情况下,将首先过滤所有项目,然后再计算任何内容。
[1, 2, 3, -1, -2].filter({ print("filtered one"); return $0 > 0 })
.reduce(0) { (total, elem) -> Int in print("counted one"); return total + 1 }
filtered one filtered one filtered one filtered one filtered one counted one counted one counted one
使用lazy
:
在这种情况下,reduce
要求计算一个项目,filter
会一直工作直到找到一个,然后 reduce
会询问对于另一个,filter
将一直工作,直到找到另一个。
[1, 2, 3, -1, -2].lazy.filter({ print("filtered one"); return $0 > 0 })
.reduce(0) { (total, elem) -> Int in print("counted one"); return total + 1 }
filtered one counted one filtered one counted one filtered one counted one filtered one filtered one
何时使用lazy
:
选项-clicking on lazy
给出了这样的解释:
来自 lazy
的讨论:
链接操作时使用惰性属性:
防止中间操作分配存储空间
或
当您只需要最终集合的一部分以避免不必要的计算时
我会添加第三个:
当您希望下游流程更快开始而不必等待上游流程先完成所有工作时
因此,例如,如果您正在搜索第一个正 Int
,则您希望在 filter
之前使用 lazy
,因为一旦找到一个,搜索就会停止,这样 filter
就不必过滤整个数组,也不必为过滤后的数组分配空间。
对于第 3 点,假设您有一个程序显示 1...10_000_000
范围内的质数,并在该范围内使用 filter
。您宁愿在找到素数时显示它们,也不愿在显示任何内容之前等待计算完所有素数。
关于arrays - 为什么以及何时在 Swift 中对数组使用惰性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51917054/