標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Go言語で必要最小限の optional パッケージを実装したものの、安全性と使い勝手の両立は難しい

安全性を担保するためには値を保持していても直接アクセスさせず、コールバック関数経由でしか参照できなくする。

func f(x optional.Value[int]) {
    x.IfSome(func(v int) {
        println("   IfSome: it has a value:", v)
    })
}

しかし、これ、コールバック関数の中で何らかのエラーが発生した時、関数 f を離脱することが非常に面倒になる。

解消方法の一つとしては for…range を使うという方法がある。

func f(x optional.Value[int]) {
    for _, v := range x {
        println("   for-range: it has a value:", v)
    }
}

この方式なら値を参照するブロック内からいきなり関数 f を離脱することもできる。これができるのは optional.Value の正体が実はサイズが 0 or 1 のスライスだからだ。それゆえ、別に Go 1.22 以降で GOEXPERIMENT=rangefunc を使わなくても使用可能となっている。だが欠点があって

  • 見掛けがループに見えてしまう
  • 間違えて for v := range x とかやりそう (v はインデックスなので常に0 になってしまう)
  • スライスという形であれ、実は中身にアクセスできることがバレバレ

やはり、Rust とか Zig とか、そういう言語がベストなのか…