Avatar
Avatar
shiz
AsyncSequenceでOptionalを扱いたい場合、nextの戻り値の型をOptionalのOptionalにしなければいけないのは、ループの終わり記号としてのnilと、要素としてのnilを区別するために仕方がないんですかね?(AsyncStream との比較のためにあえてAsyncSequence 使ってます) ちょっと不思議な気もしたのですが、nextの定義にOptionalが付いているのでそういうものなんですね...  改めて考えたらIteratorProtocol と同じですね(失礼しましたmm)。 mutating func next() async throws -> Self.Element? struct IntGenerator: AsyncSequence { typealias Element = Int? var strings: [String] struct AsyncIterator: AsyncIteratorProtocol { var current = 1 var strings: [String] fileprivate var index = 0 mutating func next() async -> Int?? { // <- ここ guard index < strings.count else { return nil } let string = strings[index] index += 1 return Int(string) } } func makeAsyncIterator() -> AsyncIterator { AsyncIterator(strings: strings) } } Task { let strings: [String] = ["1", "a", "2"] for await i in IntGenerator(strings: strings) { print(i) } } Optional(1) nil Optional(2) (edited)
Java 等の言語だと nullable の入れ子ができないので、 Iterator の API が hasNextnext に分かれていて、まず hasNext で存在を確認してから next を呼ぶという手順になっていますね。その点、 next だけで済ませられる Swift の設計はシンプルだと思います。
👍🏻 1