Nice programing

Kotlin의`forEach`에서`break` 및`continue`

nicepro 2020. 10. 9. 12:23
반응형

Kotlin의`forEach`에서`break` 및`continue`


코 틀린처럼, 아주 좋은 반복하는 기능을 가지고 forEachrepeat,하지만 난 할 수 없습니다입니다 breakcontinue운영자가 그들과 함께 작업 (로컬 및 비 로컬) :

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)
    }
}

편집 :
Kotlin의 이전 문서 에 따르면 링크가 끊어졌습니다 . 주석을 사용하여 가능해야합니다. 그러나 아직 구현되지 않았습니다.

사용자 정의 제어 구조에 대한 중단 및 계속이 아직 구현되지 않았습니다.

문제 나는 고정하지 않을 생각 때문에이 기능에 대한이, 3 세입니다.


원래 답변 :
을 제공하기 때문에 (Int) -> Unit컴파일러가 루프에서 사용되는 것을 알지 못하기 때문에 중단 할 수 없습니다.

몇 가지 옵션이 있습니다.

일반 for 루프를 사용하십시오.

for (index in 0..times - 1) {
    // your code here
}

루프가 메서드의 마지막 코드 인 경우 메서드에서 나가는 데
사용할 수 있습니다 return(또는 메서드 return value가 아닌 경우 unit).

방법 사용 계속하기 위해
반환되는 사용자 지정 반복 방법 방법을 만듭니다 Boolean.

public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
    for (index in 0..times - 1) {
        if (!body(index)) break
    }
}

이것은 1에서 5까지 인쇄됩니다. 이 경우 Java return@forEach의 키워드처럼 작동 합니다. continue즉,이 경우에는 여전히 모든 루프를 실행하지만 값이 5보다 크면 다음 반복으로 건너 뜁니다.

fun main(args: Array<String>) {
    val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    nums.forEach {
       if (it > 5) return@forEach
       println(it)
    }
}

1에서 10까지 인쇄되지만 5는 건너 뜁니다.

fun main(args: Array<String>) {
    val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    nums.forEach {
       if (it == 5) return@forEach
       println(it)
    }
}

Kotlin Playground 에서 사용해보세요 .


당신은 사용할 수 있습니다 람다 식의 반환 하는 모방 continue하거나 break따라 사용량에 있습니다.

이것은 관련 질문에서 다룹니다. Kotlin 내에서 기능 루프에있을 때 "중단"또는 "계속"을 수행하려면 어떻게해야합니까?


다음을 사용하여 휴식을 취할 수 있습니다.

//Will produce"12 done with nested loop"
//Using "run" and a tag will prevent the loop from running again. Using return@forEach if I>=3 may look simpler, but it will keep running the loop and checking if i>=3 for values >=3 which is a waste of time.
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}

다음을 통해 계속할 수 있습니다.

//Will produce: "1245 done with implicit label"
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with implicit label")
}

As anyone here recommends... read the docs :P https://kotlinlang.org/docs/reference/returns.html#return-at-labels


As the Kotlin documentation says, using return is the way to go. Good thing about kotlin is that if you have nested functions, you can use labels to explicity write where your return is from:

Function Scope Return

fun foo() {
  listOf(1, 2, 3, 4, 5).forEach {
    if (it == 3) return // non-local return directly to the caller of foo()
    print(it)
  }
  println("this point is unreachable")
}

and Local Return (it doesn't stop going through forEach = continuation)

fun foo() {
  listOf(1, 2, 3, 4, 5).forEach lit@{
    if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
    print(it)
  }
  print(" done with explicit label")
}

Checkout the documentation, it's really good :)


continue type behavior in forEach

list.forEach { item -> // here forEach give you data item and you can use it 
    if () {
        // your code
        return@forEach // Same as continue
    }

    // your code
}

for break type behavior you have to use for until

for (index in 0 until list.size) {
    val item = listOfItems[index] // you can use data item now
    if () {
        // your code
        break
    }

    // your code
}

참고URL : https://stackoverflow.com/questions/32540947/break-and-continue-in-foreach-in-kotlin

반응형