I am writing a multi-lang website.
I read the language info from users cookies, and I have several translation modules such as en.go
gr.go
etc.
The modules are of type map[string]string
.The problem here is in javascript I can do something like lang[cookies.lang]["whatever message"].'But go does not support accessing struct members in this way.
I could make switch case or
map[string]map[string]string` and map all possible languages, but this is much extra work.
So is there any way golang provides some way to access members like js brackets notation?
Not: There was a similar question on the stack, and somebody wrote to use "reflect" package, but I could not quite understand how it works and failed to reproduce by myself works and failed to reproduce by myself.

- 3,254
- 2
- 26
- 40
-
Here are some examples how to access fields of struct values based on their names using `reflect`: [one](http://stackoverflow.com/a/30889373/1705598); [two](http://stackoverflow.com/a/39968350/1705598); [three](http://stackoverflow.com/questions/30913483/golang-sort-struct-fields-in-alphabetical-order/30915092#30915092); [four](http://stackoverflow.com/a/33142636/1705598). – icza Oct 18 '16 at 00:09
-
what are the reasons for people to give minus points without a note? How silly question right ? the ones who voted minus are familiar with any kinda technology i guess – nikoss Oct 18 '16 at 07:54
-
1@nikoss I think it is because this reads very much like a "how can I write JavaScript in Go" question. You can't, they have different capabilities. All in all, I think a `map[string]map[string]string` is the right solution in Go and it should not require much more typing than using structs, dynamically find packages, or whatever else you were considering using reflection for. – Vatine Oct 18 '16 at 08:09
-
@Vatine that was the question; how to use reflection. This has nothing to do with js it was just an example of how it's done in js – nikoss Oct 18 '16 at 08:16
1 Answers
One possible route would be to use a map[string]map[string]string
.
You could then have a base package in which you declare your base translation variable and in your translation modules, you can use an init
function to populate the relevant sub-map. It's essentially optional if you want to do this as separate packages or just separate files (doing it as packages means you have better compile-time control of what languages to include, doing it as files is probably less confusing).
If you go the packages root, I suggest the following structure:
translation/base This is where you export from
translation/<language> These are "import only" packages
Then, in translation/base:
package "base"
var Lang map[string]map[string]string
And in each language-specific package:
package "<language code>"
import "language/base"
var code = "<langcode>"
func init() {
d := map[string]string{}
d[<phrase1>] = "your translation here"
d[<phrase2>] = "another translation here"
// Do this for all the translations
base.Lang[code] = d
}
Then you can use this from your main program:
package "..."
import (
"language/base"
_ "language/lang1" // We are only interested in side-effects
_ "language/lang2" // Same here...
)
Not using separate packages is (almost) the same. You simply ensure that all the files are in the same package and you can skip the package prefix for the Lang
variable.
A toy example on the Go Playground, with all the "fiddly" bits inlined.

- 20,782
- 4
- 54
- 70
-
Thats what i thought too. In the question i mentioned that but this is not the only case i need dynamic calls for thats why i upvoted but this is not exactly the answer i am looking for anyway this is the go way to do this stuff i think just it gets messy when you have a lot of stuff to call dynamically – nikoss Oct 18 '16 at 08:11