protocol Iterator { associatedtype Element associatedtype Failure: Error func _next() throws -> Element? } extension Iterator { func next() throws -> Element? { try _next() } } // 例外飛ばない版 // 本体の定義が`_next`なのは、もし`next`だとここで自己再起しちゃうから。。 extension Iterator where Failure == Never { func next() -> Element? { try! _next() } } // こういう仕組みが必要なのかもしれない // iterator.nextの呼び出しから例外が飛ばないことがXの型からわかるとき、 // dropCからも例外を飛ばないということを宣言したい // rethrows句自体はすでにあるけど、クロージャを渡した場合に限られた機能なので、 // これを拡張する。 func dropC<X: Iterator>(iterator: X, n: Int) rethrows(from iterator.next) { for _ in 0..<n { _ = try iterator.next() } }