Last active
February 17, 2020 08:58
-
-
Save pofat/8626b181459ef8846fb99d903617dc0a to your computer and use it in GitHub Desktop.
如何用 generic struct 消除 PAT 的問題
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 利用 init with closure 來自動代入 `Element` 真實的型別,而不是直接用 <某型別> 的方式來指定 | |
// 先宣告一個 generic struct | |
struct MyAnyIterator<Element> { | |
// 內部使用的 Box ,裡面就是把 closure 存起來,本身也滿足 IteratorProtocol | |
private class AnyIteratorBox<Element>: IteratorProtocol { | |
typealias Base = () -> Element? | |
private var _base: Base | |
init(_ base: @escaping Base) { | |
self._base = base | |
} | |
func next() -> Element? { | |
return _base() | |
} | |
} | |
// 把 closure 包起來的 box ( 簡單一點也可讓 box 就是個 closure type 直接存 closure) | |
private let box: AnyIteratorBox<Element> | |
init(_ body: @escaping () -> Element?) { | |
self.box = AnyIteratorBox(body) | |
} | |
} | |
// 再讓本身滿足 IteratorProtocol | |
extension MyAnyIterator: IteratorProtocol { | |
mutating func next() -> Element? { | |
return box.next() | |
} | |
} | |
// Fibonacci iterator | |
var state = (0, 1) | |
var myIterator = MyAnyIterator { () -> Int in | |
let upcomingNumber = state.0 | |
state = (state.1, state.0 + state.1) | |
return upcomingNumber | |
} | |
print(myIterator.next()) // 0 | |
print(myIterator.next()) // 1 | |
print(myIterator.next()) // 1 | |
print(myIterator.next()) // 2 | |
print(myIterator.next()) // 3 | |
print(myIterator.next()) // 5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment