Go Tips #1

May 23 2014

As I’ve been using Go more and more, I’ve picked up little relevant things here and there. I’d like to share them here whenever I have enough stockpiled.

  1. Unnamed structs in slice literals

    Let’s say we have a struct Test, and we’re constructing a slice with a literal:

    type Test struct {
        Name string
    slice := []Test{Test{Name: "test"}, Test{Name: "another test"}}

    Since the slice is already confirmed to be a slice of Test’s, I can rewrite it like this:

    slice := []Test{{Name: "test"}, {Name: "another test"}}

    This cuts down slightly on verboseness while still being clear and readable.

    UPDATE: /u/fursurely has reminded me of an even less verbose way of writing the above:

    slice := []Test{{"test"}, {"another test"}}

    This is nice, but you have to give a value for every field in the struct. For example, this is NOT valid:

    type Test2 struct {
        Field1, Field2, Field3 string
    slice := []Test2{{"test", "more"}, {"another", "test"}}

    In this case, you would have to use the second way, like this:

    slice := []Test2{{Field1: "test", Field2: "more"}, {Field1: "another", Field3: "test"}}
  2. Slice literals as function arguments

    Here is a commit on a Go library fork of mine. Previously, this function took a slice, inevitably a literal, like this:

    heresAFunction([]interface{}{heresAStruct, anotherStruct})

    It’s much cleaner to accept slices into functions in the form of variadic arguments, since variadic arguments are passed into the function as a slice anyway. Our previous example now looks like this:

    heresAFunction(heresAStruct, anotherStruct)
  3. Goroutines inside HTTP handlers

    Everytime your Go HTTP server recieves a request, it picks the appropriate function to handle it with, and start a new goroutine with that handler. This means that doing things like this are unneccesary and buggy:

    func handler(w http.ResponseWriter, r *http.Request) {
        go func() {
            // ...