英文:
How to have unshared stateful variables in 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
在其他函数中随意使用。我需要cookieJar
和client
只能在funcThatDoesRequests
函数内部访问。这可能吗?
静态变量(在伪代码示例中使用static关键字)是一种在C和PHP等语言中常见的特性。
英文:
I know that, right now (and probably forever), we won't have static variables in Go... but is there a way to protect variables in some way?
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
}
I don't want the http client
and its cookieJar
floating around so other functions can do something with them. I need the cookieJar
and client
to only be accessible inside the funcThatDoesRequests
. Is that possible?
> Static variables (see static keyword in the pseudo code example) is a feature present in languages like C and PHP, to name some common languages.
答案1
得分: 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
在多次调用中保持了 client
和 cookieJar
,但是这些名称不会泄露到包外。
英文:
Usually it's best not to worry about package-scoped globals since it's only code in your own package that can abuse them.
But if you really want, you can use a closure which is created when your package is loaded to generate the "static" variables.
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()
Now funcThatDoesRequests
maintains client
and cookieJar
over multiple calls, but the names don't leak into the package.
答案2
得分: 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) {
/* 其余的代码放在这里 */
}
/* 然后,在某个地方... */
var thing privateData
thing.Initialize()
/* 然后,您可以将 thing.Do 传递给原本需要传递 funcThatDoesRequests 的地方 */
英文:
One possibility would be to create a struct with your "private, static" variables and make your handler a method of that struct.
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 */
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论