marcio
marcio

Reputation: 10512

How to have unshared stateful variables in Go?

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.

Upvotes: 2

Views: 315

Answers (2)

Vatine
Vatine

Reputation: 21268

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 */

Upvotes: 1

Paul Hankin
Paul Hankin

Reputation: 58280

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.

Upvotes: 3

Related Questions