Golangでgotoを使ってみた
"goto"を使う ―― とても、感慨深いです。
"goto"追放キャンペーンが発生したのは、私が大学院在学中の頃でしょうか。そして、現在も"goto"に対する差別的扱いは、変っていません。"goto"なんか使ったら、それだけで『無能』扱いされ、仕事の依頼を打ち切られるような空気すらあります。
まあ、"goto"に、そこまで言われるだけの弊害があるのは確かです。特に「可読性は最悪」ですし、放置された変数が、どんな悪さをするか分かったもんではありません。メモリリークは確実で、スレッドとか使っていたら高い確率でクラッシュします。
しかし、私、学生のころ、N-BASICで"goto"使い倒していましたけど、『あれは、あれで便利でした』。
実際、プログラミング初心者には、とても便利なモノでした。初学者には、"goto"で、ラクラクプログラミングを楽しんでもらっていいんじゃないかな、私は思うのです。
ところで、調べてみたら、golangに、"goto"が実装されていました。C/C++にもありました。Pythonにもありました。Javaにもあるみたいですが、動かないようです(?)。
「使うな」と言われている割に、一応準備だけはされているのが、なかなか興味深いです。
ちゃんと動きましたので、書き残しておきます。
// go run main2.go
package main
import (
"fmt"
"time"
)
var ch1 chan interface{}
var ch2 chan interface{}
func main() {
ch1 = make(chan interface{}) // チャネルの初期化
ch2 = make(chan interface{}) // チャネルの初期化(ここでは使っていない)
go loop()
for i := 0; i < 5; i++ {
time.Sleep(3 * time.Second) // 3秒待つ
fmt.Println("send")
ch1 <- i
}
}
func loop() {
L:
fmt.Println("先頭からやりなおし")
for {
time.Sleep(1 * time.Second) // 1秒待つ
fmt.Println("loop")
//チャネルからメッセージの到着を確認する
select {
case i := <-ch1:
fmt.Println("ch1:", i)
goto L
case <-ch2:
fmt.Println("ch2")
default:
//fmt.Println("No value")
}
}
}
以上