Golangのgoto文に関して興味を持った背景
こちらの記事でコーディングテストの勉強をする際に、恥ずかしながら初めてgoto文を知ったのでこちらの記事でまとめようと思います。
具体的にgoto文が使われている箇所
実際にgolangのgithubを覗くと、こちらの箇所などで使われているようです。
rand/rand.go
func (r *Rand) Float64() float64 {
// A clearer, simpler implementation would be:
// return float64(r.Int63n(1<<53)) / (1<<53)
// However, Go 1 shipped with
// return float64(r.Int63()) / (1 << 63)
// and we want to preserve that value stream.
//
// There is one bug in the value stream: r.Int63() may be so close
// to 1<<63 that the division rounds up to 1.0, and we've guaranteed
// that the result is always less than 1.0.
//
// We tried to fix this by mapping 1.0 back to 0.0, but since float64
// values near 0 are much denser than near 1, mapping 1 to 0 caused
// a theoretically significant overshoot in the probability of returning 0.
// Instead of that, if we round up to 1, just try again.
// Getting 1 only happens 1/2⁵³ of the time, so most clients
// will not observe it anyway.
again:
f := float64(r.Int63()) / (1 << 63)
if f == 1 {
goto again // resample; this branch is taken O(never)
}
return f
}
forで書くとこんな感じですね。
rand/rand.go
func (r *Rand) Float32() float32 {
f := float32(r.Float64())
for f == 1 {
f = float32(r.Float64())
}
return f
}
使い所がいまいちわからずfor文で良いのでは?とは思ってしまいました。
ちなみにgoto文はメソッド外ではCompile Error
になります。
GoPlaygroundリンク
hoge/hoge.go
func main() {
var val int = 0
val = val + 2
if val < 5 {
goto XYZ
}
}
func PrintHello() {
XYZ:
fmt.Printf("Hello World\n")
}
// putput:
// ./prog.go:9:8: label XYZ not defined
// ./prog.go:14:1: label XYZ defined and not used
個人的な所感
う〜ん。正直for文でいいんじゃないのかなと思いますが、処理速度などが違うんですかね。