Ответ 1
Вы можете использовать return from lambda expression, который имитирует continue
или break
в зависимости от вашего использования.
Вот пример, имитирующий continue
:
(1..5).forEach {
if (it == 3) [email protected] // mimic [email protected]
// ... do something more
}
И вы можете усложниться и использовать ярлыки, когда у вас возникают проблемы с вложением или запутыванием:
(1..3).forEach [email protected] { x ->
(1..3).forEach [email protected] { y ->
if (x == 2 && y == 2) [email protected] // mimic [email protected]
if (x == 1 && y == 1) [email protected] // mimic [email protected]
// ... do something more
}
}
Если вы хотите сделать break
, вам нужно что-то вне цикла, из которого вы можете вернуться, здесь мы будем использовать функцию run()
, чтобы помочь нам:
run [email protected] {
(1..20).forEach { x ->
if (x == 5) [email protected] // mimic [email protected]
// ... do something more
}
}
Вместо run()
это может быть let()
или apply()
или что-то естественное, что вы окружаете forEach
, из которого вы хотите сломать место. Но вы также пропустите код в том же блоке после forEach
, поэтому будьте осторожны.
Это встроенные функции, поэтому они действительно не добавляют накладные расходы.
Прочтите справочные документы Kotlin для Возвраты и переходы для всех особых случаев, в том числе для анонимных функций.
Вот unit test, подтверждающий, что все это работает:
@Test fun testSo32540947() {
val results = arrayListOf<Pair<Int,Int>>()
(1..3).forEach [email protected] { x ->
(1..3).forEach [email protected] { y ->
if (x == 2 && y == 2) [email protected] // continue @outer
if (x == 1 && y == 1) [email protected] // continue @inner
results.add(Pair(x,y))
}
}
assertEquals(listOf(Pair(1,2), Pair(1,3), Pair(2,1), Pair(3,1), Pair(3,2), Pair(3,3)), results)
val results2 = arrayListOf<Int>()
run [email protected] {
(1..20).forEach { x ->
if (x == 5) [email protected]
results2.add(x)
}
}
assertEquals(listOf(1,2,3,4), results2)
}