最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Kotlin:forEach也能break和continue

 更新時間:2017年06月13日 08:46:47   投稿:lqh  
這篇文章主要介紹了詳解Kotlin:forEach也能break和continue的相關資料,需要的朋友可以參考下

詳解Kotlin:forEach也能break和continue

這樣的問題。也就是說,他們想用forEach而不是for循環(huán),因為這很fp,很洋氣(我也喜歡),

但是他們又想使用break和continue,也就是普通的流程控制語句中的控制語句。

這很不fp,因為原本有filter是用于完成這個工作的,還有flapMap。BennyHuo在他發(fā)的文章里面也說的是這種方法。

filter很fp,但是會導致兩次遍歷,這樣的話給人一股效率很低的趕腳。而Java8的Stream API就只會遍歷一次,
而且很fp。但是它會有l(wèi)ambda對象的產(chǎn)生而且實現(xiàn)超復雜(我沒看過,不清楚),而Kotlin的集合框架可是能inline掉lambda的,

少產(chǎn)生了多少對象啊,怎么能和辣雞Java同流合污呢?

有人提到使用label return,比如:

fun main(ags: Array<String>) {
 (0..100).forEach {
  if (50 <= it) return@forEach
  println(it)
 }
}

但是他做了實驗之后發(fā)現(xiàn)這玩意只能相當于continue,也就是說你只能跳出當前循環(huán),然后還是會繼續(xù)下一輪。

講道理這個你仔細想想就可以發(fā)現(xiàn)。為了搞清楚其中的道理,我們自己實現(xiàn)一個forEach。

fun Pair<Int, Int>.forEach(block: (Int) -> Unit) {
 for (i in first..second) block.invoke(i)
}

然后調用一下:

Pair(1, 100).forEach(::println)

沒毛病老鐵。

然后你會發(fā)現(xiàn),你在函數(shù)體內對block產(chǎn)生了(second - first)次調用,不論你怎么return,都只會跳出這個block,
它并不影響你之后繼續(xù)調用這個block,也就是說這個for循環(huán)不受block行為的影響。

看起來無解了,那怎么辦呢?

那么就讓我來拯救你們吧。

fun main(ags: Array<String>) {
 run outside@ {
  (0..20).forEach inside@ {
   if (10 <= it) return@outside
   println(it)
  }
 }
}

編譯之后運行結果:

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

吶,跳出去了。

就是這樣:

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

上面這是break,運行結果就上面那樣。

下面這是continue,運行結果就是continue的效果。為了讓效果表現(xiàn)的明顯,我把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了。服不服?

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

最新評論

沾益县| 昌邑市| 嘉祥县| 德兴市| 张北县| 铜梁县| 石棉县| 宜君县| 吴江市| 淮阳县| 吐鲁番市| 通城县| 调兵山市| 南安市| 新昌县| 翁牛特旗| 清流县| 乌拉特中旗| 罗田县| 嘉峪关市| 北安市| 金秀| 高邑县| 凤庆县| 个旧市| 广德县| 航空| 大厂| 昌黎县| 佛冈县| 黄石市| 襄汾县| 全州县| 洞头县| 准格尔旗| 吴堡县| 鄱阳县| 牟定县| 桦川县| 合山市| 东明县|