我在 Python 中经常使用生成器。现在我尝试在 Swift 中做类似的事情。
来自 Python 中的无限阶乘生成器。
def gen_factorial():
current = 1
N = 1
while True:
yield current
N += 1
current *= N
Swift 版本是
struct gen_factorial: Sequence, IteratorProtocol
{
var current = 1
var N = 1
mutating func next()-> Int?{
defer {
N += 1
current *= N
}
return current
}
}
我通过使用前 4 个元素来测试它
zip(1...4,
gen_factorial()
).map{$1}
并按预期获得 1, 2, 6, 24
。
但是当我想编写一个辅助函数 take(n, gen)
来简化它时,我却做不到。
func take(_ n: Int, _ it: AnyIterator<Int>) -> [Int]{
return zip(1...n, it).map {$1}
}
take(4, gen_factorial())
错误信息是
error: cannot convert value of type 'gen_factorial' to expected argument type 'AnyIterator<Int>'
如果不是 AnyIterator,它应该是什么类型?
我对 Swift 还很陌生。请帮忙。
最佳答案
AnyIterator
是符合 Iterator
(和 Sequence
)协议(protocol)的具体类型。为了将迭代器传递给该函数,您必须将其包装到 AnyIterator
中:
print(take(4, AnyIterator(gen_factorial())))
// [1, 2, 6, 24]
更好的解决方案是使函数通用,以便它采用任意序列类型作为参数:
func take<S: Sequence>(_ n: Int, _ it: S) -> [S.Element]{
return zip(1...n, it).map {$1}
}
print(take(4, gen_factorial()))
// [1, 2, 6, 24]
备注:
您可以使用现有的
prefix(_ maxLength:)
来代替辅助函数。序列
的方法:print(Array(gen_factorial().prefix(4))) // [1, 2, 6, 24]
大驼峰式大小写类型的 Swift 命名约定。
关于python - 从 Swift 中的无限迭代器或生成器中获取前 N 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56914614/