Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kousik93/65010bf511b7b7188169 to your computer and use it in GitHub Desktop.
Save kousik93/65010bf511b7b7188169 to your computer and use it in GitHub Desktop.
The curious case of Go lang variable naming convention

Being new to Go, I decided to try writing a very simple REST API. I'm writing here about the bizarre problem I encountered writing it and how it took me a very long time to find the solution. To professional Go programmers this might sound very trivial. But coming from a background of mainstream OO langages, I found this pretty unconventional.

So lets look at a simple program that handles a http POST request. The request sends along some JSON data. Usually to store and parse JSON data you create a struct similar to the structure of the incoming JSON and decode the JSON and store it in an object of the struct. Lets have a look at a sample code:

type test_struct struct {
	Test string `json:"test"`
}

func testPost(rw http.ResponseWriter, request *http.Request) {
	decoder := json.NewDecoder(request.Body)
	var t test_struct
	err := decoder.Decode(&t)
	if err != nil {
		panic(err)
	}
	fmt.Println(t.Test)
}
func main() {
	http.HandleFunc("/", testPost)
	http.ListenAndServe(":3000", nil)
}

Now if we hit the code with a CURL request like this: curl -X POST -d "{ "test": "Hello World"}" http://localhost:3000/testPost

,then we will get the response "Hello World". The described route directs the request to testPost function and our object gets filled in with appropriate values.

Great. That works! Now let us look at the struct we have defined.

type test_struct struct {
	Test string `json:"test"`
}

See that the variable name is "Test" which is different from the JSON key "test".

Here comes the issue. When I initially started writing my program, my struct looked like this:

type test_struct struct {
	test string `json:"test"`
}

Obviously, the only change here is that the variable name is all in small caps. When I tried running my code, all I got was an empty variable.

The decoder.Decode() didn't throw any error. The JSON was perfectly valid. The server was running on the correct port. The routes worked. The curl was correct. I was even sniffing the server port to check if something crazy was happening during transmission. Every single consieveable thing seemed to be correct and yet, I was getting null.

After fiddling about for a long time, I figured out what I was doing wrong, and Yes, it was the naming of the variable.

Apparently in Go, if you want to access varibles in another package, the first letter in the variable name has to be a capital ASCII [A-Z] character. So, I was not able to access and henceforth modify the variable in my function. https://golang.org/ref/spec#Exported_identifiers

I find this rule to be very bizarre. I have never encountered such a rule where naming convention of a varibale has implications on its access and I dont like it.

For those who are new to GO, reading this has hopefully saved you some time and effort.

@taddev
Copy link

taddev commented May 2, 2016

Since you're coming from OO it might be helpful to think of the difference between exported & non-exported identifiers as the difference between Public(Exported) and Private(Non-Exported) objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment