Когда использовать forEach (:) вместо for in?

как описано в массив и словарь forEach(_:) примеру методов:

вызывает заданное закрытие для каждого элемента в последовательность в то же порядок как цикл for-in.

тем не менее, адаптированный Обзор Последовательности:

последовательность-это список значений, которые вы можете пройти через один время. самый распространенный способ в перебирать элементы последовательности это использовать for-in loop.

подразумевая, что итерация последовательности по forEach(_:) или for in:

let closedRange = 1...3

for element in closedRange { print(element) } // 1 2 3

closedRange.forEach { print() } // 1 2 3

Или (Массив):

let array = [1, 2, 3]

for element in array { print(element) } // 1 2 3

array.forEach { print() } // 1 2 3

даст тот же результат.

почему forEach(_:) еще существует? Я. e в чем преимущество использования его вместо for in петли? они же с точки зрения производительности?

как предположение, это может быть синтаксическим сахаром особенно при работе с функциональное программирование.

3 ответов


никакое преимущество представления предложенное forEach. На самом деле,если вы посмотрите на исходный код на


недавно я наткнулся на случай использования, когда использование forEachбыло предпочтительнее ощутимым образом for in. Допустим, вы хотите удалить все подслои слоя. Утверждение, подобное приведенному ниже, не работает, поскольку вам нужно развернуть [CALayer]

for layer in self.videoContainerView.layer.sublayers!

если подслои равны нулю, вы получите сбой. Это заставляет вас сначала проверить, есть ли подслои. Однако,forEach делает это намного проще, как в следующем:

self.videoContainerView.layer.sublayers?.forEach { .removeFromSuperlayer() }

они более-менее взаимозаменяемы, но есть два важных отличия.

  1. break/continue только в for .. in
  2. return на forEach выйдет из закрытия, но не остановит итерацию.

причина этого в том, что for .. in - это специальная форма на языке (который позволяет перерыв и продолжать работать, как вы ожидаете). Это то, что вы не можете реализовать идентичным образом, используя сам язык.

, forEach не является специальной формой и может быть повторно реализован идентично, написав его как функцию.
extension Sequence {
    func myOwnForEach(_ body: (Self.Element) throws -> Void) rethrows {
        let it = Self.makeIterator()
        while let item = it.next() {
            body(item)
        }
    }
}