• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解Kotlin:forEach也能break和continue

java 搞代码 4年前 (2022-01-05) 44次浏览 已收录 0个评论

这篇文章主要介绍了详解Kotlin:forEach也能break和continue的相关资料,需要的朋友可以参考下

详解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) { (0..100).forEach { if (50 <= it) return@forEach println(it) } } 

但是他做了实验之后发现这玩意只能相当于continue,也就是说你只能跳出当前循环,然后还是会继续下一轮。

讲道理这个你仔细想想就可以发现。为了搞清楚其中的道理,我们自己实现一个forEach。

 fun Pair.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) { run outside@ { (0..20).forEach inside@ { if (10 <= it) return@outside print<span style="color:transparent">来源gaodai#ma#com搞*!代#%^码网</span>ln(it) } } } 

编译之后运行结果:

 0 1 2 3 4 5 6 7 8 9 Process finished with exit code 0 

呐,跳出去了。

把label的名字起的清真一点,就是这样:

 run breaking@ { (0..20).forEach continuing@ { if (10 <= it) return@breaking println(it) } } 

上面这是break,运行结果就上面那样。

下面这是continue,运行结果就是continue的效果。为了让效果表现的明显,我把println复制了一下,
分别在if前后,这样可以很清楚地看到效果。

 run breaking@ { (0..20).forEach continuing@ { print(it) if (10 <= it) return@continuing println(it) } } 

运行一下:

 00 11 22 33 44 55 66 77 88 99 1011121314151617181920 Process 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了。服不服?

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

以上就是详解Kotlin:forEach也能break和continue的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解Kotlin:forEach也能break和continue

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址