如何将序列转换为数组或Swift中的序列是否结束?
How to convert Sequence to Array or is there an end of Sequence in Swift?
根据文档:
init(_ s: S) where Element == S.Element, S : Sequence
Creates an array containing the elements of a sequence.
struct Test: IteratorProtocol, Sequence {
let id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
id < 10 ? Test(id + 1) : nil
}
}
let test = Test(5)
let arr = Array(test)
编译通过。甚至不会抛出任何运行时错误。
但是我得到的不是数组 [5, 6, 7, 8, 9],而是一个无限循环! next()
被无限多次调用。
我认为 next()
中的 nil
是序列结束的自然指示符。但显然不是。
self.id
永远不会改变,所以它永远不会到达 10
。
应该是这样的
struct Test: IteratorProtocol, Sequence {
var id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
defer { id += 1 }
return id < 10 ? self : nil
}
}
print(Array(Test(6)))
另一个例子
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
let threeToGo = Countdown(count: 3)
for i in threeToGo {
print(i)
}
// Prints "3"
// Prints "2"
// Prints "1"
出现了,有一个built-in function,完全符合我在这个post中最初问题的逻辑。
sequence(first:next:)
Returns a sequence formed from first and repeated lazy applications of next.
struct Test {
var id: Int
init(_ id: Int) {
self.id = id
}
}
let seq = sequence(first: Test(5), next: { test in
let id = test.id + 1
return id < 10 ? Test(id) : nil
})
let arr = Array(seq)
根据文档:
init(_ s: S) where Element == S.Element, S : Sequence
Creates an array containing the elements of a sequence.
struct Test: IteratorProtocol, Sequence {
let id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
id < 10 ? Test(id + 1) : nil
}
}
let test = Test(5)
let arr = Array(test)
编译通过。甚至不会抛出任何运行时错误。
但是我得到的不是数组 [5, 6, 7, 8, 9],而是一个无限循环! next()
被无限多次调用。
我认为 next()
中的 nil
是序列结束的自然指示符。但显然不是。
self.id
永远不会改变,所以它永远不会到达 10
。
应该是这样的
struct Test: IteratorProtocol, Sequence {
var id: Int
init(_ id: Int) {
self.id = id
}
mutating func next() -> Test? {
defer { id += 1 }
return id < 10 ? self : nil
}
}
print(Array(Test(6)))
另一个例子
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
let threeToGo = Countdown(count: 3)
for i in threeToGo {
print(i)
}
// Prints "3"
// Prints "2"
// Prints "1"
出现了,有一个built-in function,完全符合我在这个post中最初问题的逻辑。
sequence(first:next:)
Returns a sequence formed from first and repeated lazy applications of next.
struct Test {
var id: Int
init(_ id: Int) {
self.id = id
}
}
let seq = sequence(first: Test(5), next: { test in
let id = test.id + 1
return id < 10 ? Test(id) : nil
})
let arr = Array(seq)