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

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

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

问题

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

英文:

I have a code:

  1. var test string
  2. func main() {
  3. http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
  4. test = "index"
  5. })
  6. fmt.Println(test)
  7. if error := http.ListenAndServe(":9001", nil); error != nil {
  8. log.Fatal("Error!", error)
  9. }
  10. }

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请求结束后再终止,你可以这样做:

  1. var test string
  2. var doneCh = make(chan bool, 1)
  3. func main() {
  4. http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
  5. test = "index"
  6. select {
  7. case doneCh <- true:
  8. default:
  9. }
  10. })
  11. go func() {
  12. <-doneCh
  13. fmt.Println(test)
  14. }()
  15. if error := http.ListenAndServe(":9001", nil); error != nil {
  16. log.Fatal("Error!", error)
  17. }
  18. }

这里使用一个通道来保护“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:

  1. var test string
  2. var doneCh = make(chan bool, 1)
  3. func main() {
  4. http.HandleFunc(&quot;/&quot;, func(writer http.ResponseWriter, request *http.Request) {
  5. test = &quot;index&quot;
  6. select {
  7. case doneCh &lt;- true:
  8. default:
  9. }
  10. })
  11. go func() {
  12. &lt;-doneCh
  13. fmt.Println(test)
  14. }()
  15. if error := http.ListenAndServe(&quot;:9001&quot;, nil); error != nil {
  16. log.Fatal(&quot;Error!&quot;, error)
  17. }
  18. }

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:

确定