emahiro/b.log

日々の勉強の記録とか育児の記録とか。

Go の range over func は nil で panic する

Go 1.23 から導入された range-over func を使うときの注意点として、range にわたす iterator 型のメソッドは nil を返してはいけない、というものがありました。
具体的には以下のコードで range-over func にアサインしてる NilFn は返り値が nil になるときに nilpo で panic します。

package main

import (
    "fmt"
    "iter"
)

func main() {
    for i := range Fn([]int64{1}) {
        fmt.Println(i)
    }
    for i := range Fn([]int64{}) {
        fmt.Println(i)
    }
    for i := range NilFn([]int64{}) {
        fmt.Println(i)
    }
}

func Fn(userIDs []int64) iter.Seq2[int64, error] {
    if len(userIDs) == 0 {
        return func(func(int64, error) bool) {}
    }
    return func(func(int64, error) bool) {}
}

func NilFn(userIDs []int64) iter.Seq2[int64, error] {
    if len(userIDs) == 0 {
        return nil
    }
    return func(func(int64, error) bool) {}
}

https://go.dev/play/p/VU4kff9_evd

range-over func に割り当てる iterator 型の関数を実装するときに、「何も処理をしない」ということをする場合、からの iter 型を返す必要がありました。