2015-11-19 9 views
21

jak poniżej, chcę zatrzymać dosłowne coś jak breakKażdy sposób, aby zatrzymać blok dosłowne w szybkim

var numbers = [1,2,3,4] 
numbers.forEach { 
    if $0 % 2 == 0 { 
     break 
    } 
} 
+0

co próbujesz zrobić? –

+0

Tylko przykład tutaj, po prostu chcę kontrolować przepływ. –

+0

Rozwiązałem. Zobacz http://stackoverflow.com/questions/33793880/any-way-to-stop-a-block-literal-in-swift/34787167#34787167 –

Odpowiedz

45

forEach nie jest pętlą (jest to blok przeszedł do pętli, ale nie sama pętla), lub dokładniej, forEach nie jest częścią Swift's Flow Flow. Dlatego nie można używać break ani continue.

Wystarczy użyć pętli for-in.


przykład:

var numbers = [ 1,2,3,4] 

func firstEvenNumber(inArray array: [Int]) -> Int? { 

    var firstMatch : Int? 

    for number in numbers { 
     if (number % 2) == 0 { 
      firstMatch = number 
      break 
     } 
    } 
    return firstMatch 
} 

firstEvenNumber(inArray: numbers) // 2 

można wykorzystywać return wewnątrz zamknięcia forEach, ale nie przerwa pętli, a jedynie powraca blok w aktualne przejście.

var numbers = [ 1,2,3,4] 

func evenNumbers(inArray: [Int]) -> [Int] { 

    var matches : [Int] = [] 

    numbers.forEach{ 
     if $0 % 2 == 0 { 
      matches.append($0) 
      return 
     } 
    } 
    return matches 
} 

evenNumbers(numbers) // [2,4] 
+0

w rzeczywistości, w drugim przykładzie "return" nic nie robi. Usuń go, a wynik będzie taki sam. Aby zobaczyć jak to działa w foreach, spróbuj tego: inArray.forEach { jeśli $ 0% 2 = 0 { powrót } matches.append ($ 0) !} – Aleksandr

+0

@Aleksandr to jest właśnie punkt. 'return' jest dostępne wewnątrz' forEach', ale nie ma pożądanego efektu PO. –

+0

Więc użyj: [y enumerateObjectsUsingBlock:^(id x, indeks NSUInteger, BOOL * stop) {}]; :) – Aleksandr

6

Dokument został wyjaśniony.

/// - Note: You cannot use the `break` or `continue` statement to exit the 
    /// current call of the `body` closure or skip subsequent calls. 
    /// - Note: Using the `return` statement in the `body` closure will only 
    /// exit from the current call to `body`, not any outer scope, and won't 
    /// skip subsequent calls. 

Ale chciałbyś spróbować.

extension CollectionType { 

    /// Use as 
    /// 
    ///  let num = [1,2,3,4,5] 
    ///  num.forEach{ 
    ///  if $1 > 3 { $2 = true } 
    ///  print($0,$1) 
    ///  } 
    func forEach(body: ((Self.Generator.Element, Int, inout Bool) -> Void)) { 
     var stop = false 
     let enumerate = self.enumerate() 
     for (index,value) in enumerate { 
      if stop { break } 
      body(value,index,&stop) 
     } 
    } 

    /// Use as 
    /// 
    ///  let num = [1,2,3,4,5] 
    ///  num.forEach{ 
    ///  if $0 > 3 { $1 = true } 
    ///  print($0) 
    ///  } 
    func forEach(body: ((Self.Generator.Element, inout Bool) -> Void)) { 
     var stop = false 
     for value in self { 
      if stop { break } 
      body(value,&stop) 
     } 
    } 
} 
Powiązane problemy