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")
		}
	}
}

以上

2022/02,江端さんの技術メモ

Posted by ebata