如何关闭一个通道并打破一个永远的循环

173 阅读1分钟

这个例子向我们展示了你如何关闭一个通道并打破一个永远的循环。通常情况下,只要接收器不依赖于通道的状态(打开/关闭),你就不需要关闭一个通道。然而,我个人会关闭以备不时之需。我们的例子需要知道通道是否关闭,以便它能安全地退出循环。值得注意的是,总是由发送方关闭通道,而不是由接收方关闭。

例子

这两个例子都是做同样的事情,所以只是展示一下:

package main

import (
	"fmt"
)

func main() {
	fmt.Println("begin")

	teams := []string{"Fenerbahce", "Arsenal", "Monaco", "Juventus"}

	msg := make(chan string)

	go list(msg, teams)

	// Until the channel is closed, print the received message.
	for m := range msg {
		fmt.Println(m)
	}

	fmt.Println("done")
	fmt.Println("end")
}

func list(msg chan<- string, teams []string) {
	for _, team := range teams {
		msg <- fmt.Sprintf("Forza %s!", team)
	}

	// Close channel to instruct the main goroutine to stop waiting for new messages.
	close(msg)
}
package main

import (
	"fmt"
)

func main() {
	fmt.Println("begin")

	teams := []string{"Fenerbahce", "Arsenal", "Monaco", "Juventus"}

	msg := make(chan string)

	go list(msg, teams)

	// Indefinitely wait for the channel to return something.
	for {
        // Until the channel is closed, print the received message otherwise break the loop.
		m, open := <-msg
		if !open {
			fmt.Println("done")
			break
		}

		fmt.Println(m)
	}

	fmt.Println("end")
}

func list(msg chan<- string, teams []string) {
	for _, team := range teams {
		msg <- fmt.Sprintf("Forza %s!", team)
	}

	// Close channel to instruct the main goroutine to stop waiting for new messages.
	close(msg)
}
begin
Forza Fenerbahce!
Forza Arsenal!
Forza Monaco!
Forza Juventus!
done
end