Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - Exit outer function from closure

Tags:

swift

kotlin

In Kotlin, you can return from an outer function from a closure.

   fun main(args: Array<String>) {
     val letters = listOf("A", "B", "C")

     fun lookForLetter(letter: String, letters: List<String>){
        letters.forEach { l ->
          if (l == letter) {
            println("Found")
            return
          }
          println(l)
        }
        println("Completed")
      }

      lookForLetter("A", letters = letters)
   }

Output:

Found

In Swift, return exits execution of the closure

var letters = ["A", "B", "C"]

func lookForLetter(letter: String, letters: [String]) {
    letters.forEach { (l) in
        if l == letter {
            print("Found");
            return
        }
        print(l)
    }
    print("Completed")
}

lookForLetter(letter: "A", letters: letters)

Output:

Found

B

C

Completed

Is there a way to achieve the same result in Swift?

like image 284
Gregory Prosper Avatar asked Dec 01 '17 04:12

Gregory Prosper


2 Answers

Swift does not have non-local returns from closures. In other words, there is no direct way to return out of multiple levels. This only works with inlined functions in Kotlin, but Swift does not have this distinction.

There are other collection methods which stop once an element is found, for example index(where:).

func lookForLetter(letter: String, letters: [String]) {
    guard let _ = letters.index(where: { (l) in
        if l == letter {
            print("Found");
            return true
        }
        print(l)
        return false
    }) else {
        print("Completed")
        return
    }
}
like image 176
ephemient Avatar answered Oct 22 '22 01:10

ephemient


Hey in swift you do like this

func lookForLetter(letter: String, letters: [String]) {
for l in letters {
    if l == letter {
        print("Found");
        return;
    }
    print(l)
}
print("Completed")

}

also

Using the forEach method is distinct from a for-in loop in two important ways:

  1. You cannot use a break or continue statement to exit the current call of the body closure or skip subsequent calls.

  2. Using the return statement in the body closure will exit only from the current call to body, not from any outer scope, and won’t skip subsequent calls.

https://developer.apple.com/documentation/swift/array/1689783-foreach

like image 26
Ashwin Sathawane Avatar answered Oct 22 '22 00:10

Ashwin Sathawane