安全性を担保するためには値を保持していても直接アクセスさせず、コールバック関数経由でしか参照できなくする。
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 とか、そういう言語がベストなのか…