如何在Go中拥有非共享状态变量?

时间:2014-12-01 10:03:07

标签: static go

我知道,现在(可能永远),我们在Go中没有静态变量...但有没有办法以某种方式保护变量?

import (
    "net/http"
    "net/http/cookiejar"
)

func funcThatDoesRequests(request Request) (response Response, e error){
  static cookieJar, _ := cookiejar.New(nil)
  static client := http.Client{ Jar: cookieJar }
  response, e = client.Do(handshakeRequest)
  return
}

我不希望http client及其cookieJar浮动,因此其他功能可以对它们做些什么。我需要cookieJarclient只能在funcThatDoesRequests内访问。这可能吗?

  

Static variables(请参阅伪代码示例中的static关键字)是C和PHP等语言中的一个特性,用于命名一些常用语言。

2 个答案:

答案 0 :(得分:3)

通常最好不要担心软件包范围的全局变量,因为它只是你自己的软件包中可以滥用它们的代码。

但是如果你真的想要,你可以使用一个在你的包被加载时创建的闭包来生成"静态"变量

func makeFunc() func(req Request)(Response, error) {
    cookieJar, _ := cookiejar.New(nil)
    client := http.Client{Jar: cookieJar}
    return func(req Request)(Response, error) {
        return client.Do(handshakeRequest)
    }
}

var funcThatDoesRequests = makeFunc()

现在funcThatDoesRequests通过多次通话维护clientcookieJar,但这些名称不会泄漏到包裹中。

答案 1 :(得分:1)

一种可能性是使用“私有,静态”变量创建一个结构,并使您的处理程序成为该结构的方法。

type privateData struct {
    jar *cookiejar.Jar
    client http.Client
}

func (r *privateData) Initialize() {
    r.jar = cookiejar.New(nil)
    r.client = http.Client{Jar: r.jar}
}

func (r *privateData) Do (request Request) (response Response, e error) {
    /* Rest of the code goes here */
}

/* then, somewhere... */
var thing privateData
thing.Initialize()
/* then you can pass thing.Do where you would have passed funcThatDoesRequests */