Sequences für for ... in - wurzelsand/swift-memos GitHub Wiki
- Protocol
Sequence
undIteratorProtocol
subscript
Ich hätte gerne eine Colors
-Struktur, die sich wie ein Array verhält:
var colors = Colors()
for color in colors {
print(color) // Red Green Blue Yellow
}
colors[0] = "Black"
print(colors[0]) // Black
struct Colors {
var values: [String] = ["Red", "Green", "Blue", "Yellow"]
subscript(i: Int) -> String {
get {
values[i]
}
set {
values[i] = newValue
}
}
}
extension Colors: Sequence {
func makeIterator() -> ColorsIterator {
ColorsIterator(values: values)
}
}
struct ColorsIterator: IteratorProtocol {
let values: [String]
var index = 0
init(values: [String]) {
self.values = values
}
mutating func next() -> String? {
if index >= values.count {
return nil
}
defer {
index += 1
}
return values[index]
}
}
Hier geht es auch einfacher:
extension Colors: Sequence {
func makeIterator() -> IndexingIterator<[String]> {
values.makeIterator()
}
}
Wenn ich selber einen generischen IndexingIterator
erstellen möchte:
struct ColorsIterator<Elements>: IteratorProtocol where Elements: Collection {
typealias Element = Elements.Element
let values: Elements
var index: Elements.Index
init(values: Elements) {
self.values = values
self.index = values.startIndex
}
mutating func next() -> Element? {
if index == values.endIndex {
return nil
}
defer {
index = values.index(after: index)
}
return values[index]
}
}
extension Colors: Sequence {
func makeIterator() -> ColorsIterator<[String]> {
ColorsIterator(values: self.values)
}
}
-
Wenn ich wirklich nur Arrays erlauben möchte:
struct ColorsIterator<T>: IteratorProtocol { let values: [T] var index = 0 init(values: [T]) { self.values = values } mutating func next() -> T? { if index >= values.count { return nil } defer { index += 1 } return values[index] } } extension Colors: Sequence { func makeIterator() -> ColorsIterator<String> { ColorsIterator(values: self.values) } }
Beachte, dass
makeIterator
nichtColorsIterator<[String]>
sondernColorsIterator<String>
zurückgibt.