How to access to the global variable from an anonymous function in the Go?

huangapple go评论85阅读模式
英文:

How to access to the global variable from an anonymous function in the Go?

问题

在匿名函数中如何更改test变量的值?谢谢!

英文:

I have a code:

var test string

func main() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
        test = "index"
    })

    fmt.Println(test)

	if error := http.ListenAndServe(":9001", nil); error != nil {
		log.Fatal("Error!", error)
	}
}

How to change the value of the test variable in the anonymous function? I will be thankful!

答案1

得分: 5

HTTP处理程序确实更改了全局变量;但是你没有保护对全局变量的访问,因此存在竞态条件。也就是说,在你的“fmt.Println(test)”运行之前,"http.HandleFunc"已经运行了。

我假设这只是一个玩具示例:如果你想要改变你的代码,等待值被改变/等待HTTP请求结束后再终止,你可以这样做:

var test string
var doneCh = make(chan bool, 1)

func main() {
    http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
        test = "index"
        select {
        case doneCh <- true:
        default:
        }
    })

    go func() {
        <-doneCh
        fmt.Println(test)
    }()

    if error := http.ListenAndServe(":9001", nil); error != nil {
        log.Fatal("Error!", error)
    }
}

这里使用一个通道来保护“test”的状态。在真实的代码中,更可能使用sync.Oncesync.Mutex。另外,我应该提到(希望你已经意识到)当可能时,应该尽量避免改变全局状态。

英文:

The HTTP handler does change your global variable; however you don't protect access to the global variable and thus have a race condition. That is to say fmt.Println(test) runs before your http.HandleFunc.

I'm assuming this is a toy example: If you want to change your code to wait for the value to be changed / wait for an HTTP hit, before terminating, then you could do this:

var test string
var doneCh = make(chan bool, 1)

func main() {
	http.HandleFunc(&quot;/&quot;, func(writer http.ResponseWriter, request *http.Request) {
		test = &quot;index&quot;
		select {
		case doneCh &lt;- true:
		default:
		}
	})

	go func() {
		&lt;-doneCh
		fmt.Println(test)
	}()

	if error := http.ListenAndServe(&quot;:9001&quot;, nil); error != nil {
		log.Fatal(&quot;Error!&quot;, error)
	}
}

This uses a channel to guard the state of test. In real code it would be more likely to use sync.Once or sync.Mutex. Also, I should mention (and I hope you already realize) mutating global state is always something to be avoided when possible.

huangapple
  • 本文由 发表于 2014年4月18日 00:32:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/23138688.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定