Для In vs While Let: Почему реализация карты Swift такая, какая она есть? - PullRequest
2 голосов
/ 26 апреля 2019

Этот вопрос связан с видео @ twostraws о том, как Apple реализовала Sequence.map

Вот как Apple это делает:

@inlinable
  public func map<T>(
    _ transform: (Element) throws -> T
  ) rethrows -> [T] {

    let initialCapacity = underestimatedCount
    var result = ContiguousArray<T>()
    result.reserveCapacity(initialCapacity)

    var iterator = self.makeIterator()

    // Add elements up to the initial capacity without checking for regrowth.
    for _ in 0..<initialCapacity {
      result.append(try transform(iterator.next()!))
    }
    // Add remaining elements, if any.
    while let element = iterator.next() {
      result.append(try transform(element))
    }
    return Array(result)
  }

Я понимаю блестящее использование underestimatedCount, чтобы зарезервировать емкость массива до начала добавления, но я не понимаю гайки и болты петель for _ in и while let внизу .

Почему эта реализация цикла более оптимальна, чем простой вызов:

while let element = iterator.next() {
    result.append(try transform(element))
}

для всего Sequence?

------ РЕДАКТИРОВАТЬ: Дальнейшие исследования ------

Я понимаю причину использования while let, for _ in и принудительного развертывания в изоляции. Этот вопрос касается того, почему этот подход использования обоих по одному оптимален в этом сценарии.

Что еще более запутанно, так это то, что при просмотре большего количества кода Apple вы видите, что filter использует while let для итерации своих элементов, но сокращает использование for element in self вместо создания итератора.

Так много загадок!

...