在下面的代码中,即使 enumareted() 返回一个 EnumeratedSequence 对象,(k, v) 也是一个元组。是编译器的魔法将其变成了元组吗?如何通过代码实现这一目标 - 将 EnumeratedSequence 转换为元组?
var str = "Hello, playground"
for (k, v) in str.characters.enumerated() {
print("\(k) - \(v)")
}
没有魔法或转变。一切都没有改变。 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
的目的是让你不必必须这样做;已经为你做好了。
你是对的。
.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