时间:2021-05-19
详解Kotlin:forEach也能break和continue
这样的问题。也就是说,他们想用forEach而不是for循环,因为这很fp,很洋气(我也喜欢),
但是他们又想使用break和continue,也就是普通的流程控制语句中的控制语句。
这很不fp,因为原本有filter是用于完成这个工作的,还有flapMap。BennyHuo在他发的文章里面也说的是这种方法。
filter很fp,但是会导致两次遍历,这样的话给人一股效率很低的赶脚。而Java8的Stream API就只会遍历一次,
而且很fp。但是它会有lambda对象的产生而且实现超复杂(我没看过,不清楚),而Kotlin的集合框架可是能inline掉lambda的,
少产生了多少对象啊,怎么能和辣鸡Java同流合污呢?
有人提到使用label return,比如:
fun main(ags: Array<String>) { (0..100).forEach { if (50 <= it) return@forEach println(it) }}但是他做了实验之后发现这玩意只能相当于continue,也就是说你只能跳出当前循环,然后还是会继续下一轮。
讲道理这个你仔细想想就可以发现。为了搞清楚其中的道理,我们自己实现一个forEach。
fun Pair<Int, Int>.forEach(block: (Int) -> Unit) { for (i in first..second) block.invoke(i)}然后调用一下:
Pair(1, 100).forEach(::println)没毛病老铁。
然后你会发现,你在函数体内对block产生了(second - first)次调用,不论你怎么return,都只会跳出这个block,
它并不影响你之后继续调用这个block,也就是说这个for循环不受block行为的影响。
看起来无解了,那怎么办呢?
那么就让我来拯救你们吧。
fun main(ags: Array<String>) { run outside@ { (0..20).forEach inside@ { if (10 <= it) return@outside println(it) } }}编译之后运行结果:
0123456789Process finished with exit code 0呐,跳出去了。
把label的名字起的清真一点,就是这样:
run breaking@ { (0..20).forEach continuing@ { if (10 <= it) return@breaking println(it) }}上面这是break,运行结果就上面那样。
下面这是continue,运行结果就是continue的效果。为了让效果表现的明显,我把println复制了一下,
分别在if前后,这样可以很清楚地看到效果。
运行一下:
001122334455667788991011121314151617181920Process finished with exit code 0而且只进行了一次迭代,非常清真,效率看起来也比较高。
如何证明只有一次迭代?我使用jd-gui逆向了刚才的代码,结果:
public final class _5Kt{ public static final void main(@NotNull String[] args) { Intrinsics.checkParameterIsNotNull(args, "args"); int $i$a$1$run; Iterable $receiver$iv = (Iterable)new IntRange(0, 20); int $i$f$forEach; for (Iterator localIterator = $receiver$iv.iterator(); localIterator.hasNext();) { int element$iv = ((IntIterator)localIterator).nextInt();int it = element$iv; int $i$a$1$forEach; System.out.print(it); if (10 <= it) { break; } System.out.println(it); } }}确实只有一次,而且jd-gui直接把我的行为反编译为break了。服不服?
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一、jqueryeach循环,要实现break和continue的功能:break----用returnfalse;continue--用returnture;
有两种可以用在循环中的声明:break和continue。JavaScriptbreak和continue声明有两种特殊的声明可用在循环内部:break和con
javascript:break和continue是两个用在内部循环的特殊语句。使用break语句跳出循环;用continue语句来跳出当前的循环继续下面的值。
break和continue的区别和作用:break用于完全结束一个循环[一般只退出一重循环],跳出循环体执行循环后面的语句continue是跳过当次循环中剩下
前面each方法中掉了一个方面没有说,就是源码中的$break和$continue。这两个变量是预定义的,其作用相当于普通循环里面的break和continue