EnumeratedSequence 如何最终成为元组?

问题描述 投票:0回答:2

在下面的代码中,即使 enumareted() 返回一个 EnumeratedSequence 对象,(k, v) 也是一个元组。是编译器的魔法将其变成了元组吗?如何通过代码实现这一目标 - 将 EnumeratedSequence 转换为元组?

var str = "Hello, playground"

for (k, v) in str.characters.enumerated() {
    print("\(k) - \(v)")
}
swift swift3 tuples
2个回答
2
投票

没有魔法或转变。一切都没有改变。 EnumeratedSequence is 元组(对)的序列。

for
只是依次检查每个元组。

因此,实际上(但简化了,因为 EnumeratedSequence 是“惰性的”),

"Hello, playground".characters.enumerated()
已经是:

   [(0,"H"), (1,"e"), ...]

您使用

for
所做的就是循环遍历它。

确实,如果你要探索

Array(str.characters.enumerated())

...这正是您所看到的——元组数组。

您可以自己生成等效的元组;例如:

var str = "Hello, playground"
for i in 0..<str.characters.count {
    let (k,v) = (i, Array(str.characters)[i])
    print("\(k) - \(v)")
}

enumerated
的目的是让你不必必须这样做;已经为你做好了。


0
投票

你是对的。

.enumerated()
返回一个
EnumeratedSequence
,它不是元组数组。

编译器的魔力在于

for ... in
语句。

for ... in
适用于序列并调用该序列迭代器的
.next()
函数。

.next()
函数生成元组。元组是下面代码中的
Element
typealias

extension EnumeratedSequence.Iterator: IteratorProtocol, Sequence {
  /// The type of element returned by `next()`.
  public typealias Element = (offset: Int, element: Base.Element)

  /// Advances to the next element and returns it, or `nil` if no next element
  /// exists.
  ///
  /// Once `nil` has been returned, all subsequent calls return `nil`.
  @inlinable
  public mutating func next() -> Element? {
    guard let b = _base.next() else { return nil }
    let result = (offset: _count, element: b)
    _count += 1 
    return result
  }
}

魔法! 🧙🪄✨

https://github.com/apple/swift/blob/master/stdlib/public/core/Algorithm.swift#L146

© www.soinside.com 2019 - 2024. All rights reserved.