Reputation: 10449
In C++ you can write things like this:
std::string foo()
{
const static std::vector<std::string> unchanging_data_foo_uses = {"one", "two", "three"};
...
}
I've always thought one important advantage of this is that this member only needs to be setup once and then on subsequent calls nothing needs to be done and it's just sitting there so that the function can do its work. Is there a nice way to do this in Go? Maybe the compiler is smart enough to see if a variable's value does not depend on the arguments then it can treat it like the above code and not do any re-evaluation?
In my specific case I am writing a Go function to convert a number into words (e.g. 42 -> "forty-two"). The following code works, but I feel dirty about work being done to setup the string arrays on every call, especially since it is recursive:
func numAsWords(n int) string {
units := [20]string{
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
}
tens := [10]string{
// Dummies here just to make the indexes match better
"",
"",
// Actual values
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety",
}
if n < 20 {
return units[n]
}
if n < 100 {
if n % 10 == 0 {
return tens[n / 10]
}
return tens[n / 10] + "-" + units[n % 10]
}
if n < 1000 {
if n % 100 == 0 {
return units[n / 100] + " hundred"
}
return units[n / 100] + " hundred and " + numAsWords(n % 100)
}
return "one thousand"
}
Upvotes: 2
Views: 2401
Reputation: 1
You can define those variables in a closure retained by your function when it is created. (You define and immediately call an anonymous function that creates these arrays, then creates and returns your function. The anonymous function's return value (your function) is then assigned to a global variable.
This solution is totally a hack - both because it's horribly unreadable (What's in that array?), and because you're abusing closures to avoid cluttering your global namespace. A better idea would probably to make your function a class method.
But my solution achieves your goals: arrays are only defined once, and don't clutter ANY namespace.
Upvotes: 0
Reputation: 99195
You can you global variables, it's completely acceptable in go, specially for that specific case.
And while you can't use the keyword const with arrays, you can use something like:
//notice that since they start with lower case letters, they won't be
// available outside this package
var (
units = [...]string{...}
tens = [...]string{ ... }
)
func numAsWords(n int) string { ... }
Upvotes: 5
Reputation: 37806
The concept of static variables do not exist in Go.
However, you can still achieve what you want by marking them as constant.
Constants in Go are just that—constant. They are created at compile time, even when defined as locals in functions
https://golang.org/doc/effective_go.html#constants
Upvotes: 4