Котлин имеет очень хорошие функции перебора, как forEach
или repeat
, но я не в состоянии сделать break
и continue
операторы работают с ними (как местный , так и нелокальным):
repeat(5) {
break
}
(1..5).forEach {
continue@forEach
}
Цель состоит в том, чтобы имитировать обычные циклы с функциональным синтаксисом как можно ближе. Это определенно было возможно в некоторых старых версиях Kotlin, но мне сложно воспроизвести синтаксис.
Проблема может заключаться в ошибке с этикетками (M12), но я думаю, что первый пример все равно должен работать.
Мне кажется, что я где-то читал про специальный трюк / аннотацию, но не нашел ни одной ссылки на эту тему. Может выглядеть так:
public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
for (index in 0..times - 1) {
body(index)
}
}
continue@label
иbreak@label
функций), см связанный с этим вопрос: stackoverflow.com/questions/34642868/...break
иcontinue
для них, или ищете альтернативные ответы, которые делают то же самое. Кажется, что первое имеет место, потому что вы отвергли второе.Ответы:
Изменить :
согласно документации Kotlin , это возможно с использованием аннотаций.
Исходный ответ :
поскольку вы указываете a
(Int) -> Unit
, вы не можете оторваться от него, поскольку компилятор не знает, что он используется в цикле.У вас есть несколько вариантов:
Используйте обычный цикл for:
Если цикл - это последний код в методе, который
вы можете использовать
return
для выхода из метода (илиreturn value
если это неunit
метод).Использование метода
Создайте собственный метод метода повторения, который возвращается
Boolean
для продолжения.источник
break
иcontinue
работаем только петлями.forEach
,repeat
а все остальные методы - это просто методы, а не циклы. Йоав представлены некоторые варианты , ноbreak
иcontinue
просто не Мент работу методов.continue@label
иbreak@label
функций), см связанный с этим вопрос: stackoverflow.com/questions/34642868/...Это напечатает от 1 до 5.
return@forEach
Действует как ключевое словоcontinue
в Java, что означает, что в этом случае он по-прежнему выполняет каждый цикл, но переходит к следующей итерации, если значение больше 5.Это напечатает от 1 до 10, но пропустит 5.
Попробуйте их на площадке Kotlin Playground .
источник
continue
иbreak
: pl.kotl.in/_LAvET-wXРазрыва можно добиться с помощью:
И продолжения можно добиться с помощью:
Как любой здесь рекомендует ... прочтите документы: P https://kotlinlang.org/docs/reference/returns.html#return-at-labels
источник
@loop
дает тот же желаемый результат.transform
где вы можете сломаться при определенных условиях, например.reduceReturnIf(acc, value, returnIf: func)
Вы можете использовать выражение return из лямбда, которое имитирует
continue
или вbreak
зависимости от вашего использования.Это рассматривается в соответствующем вопросе: как мне выполнить «прерывание» или «продолжение» в функциональном цикле внутри Kotlin?
источник
Как говорится в документации Kotlin , использование
return
- это правильный выбор. В kotlin хорошо то, что если у вас есть вложенные функции, вы можете использовать метки, чтобы явно указать, откуда происходит ваш возврат:Функция Scope Return
и местный возврат (не прекращается forEach = continue)
Ознакомьтесь с документацией, это действительно хорошо :)
источник
forEach
continue
тип поведения вforEach
для
break
поведения типа, которое вы должны использовать,for in until
илиfor in
в соответствии со списком,Nullable
илиNon-Nullable
Для списка, допускающего значение NULL :
Для списка, не допускающего значения NULL :
источник
Оператор Break для вложенных циклов forEach ():
Результат:
Оператор продолжения с анонимной функцией:
Результат:
источник
возможно изменить для каждого на
это работает для хэш-карт
источник
Я знаю, что это может быть не совсем связано с break continue for
forEach
, но так как1.3.70
у нас есть,scan
чтобы мы могли получить хотя бы промежуточные результаты.Итак, теперь, если вы можете собрать все результаты (аналогичные
map
), которые могут вам не понадобиться, однако, если вы позволите ему закончить, вы можете пропустить разрыв и просто проверить окончательный массив.IMHO, базовое функциональное программирование на самом деле не учитывает
transform
операцию, которая должна выпрыгнуть посередине, не завершив ее. Чтобы действительно решить эту проблему, нам нужно создать функцию, которая учитывает условие возврата, например.источник