Very late to the party learning this. Originally my excuse was it wasn’t available on NetBSD, but that was years ago now, so my other excuse was I didn’t like quite how opinionated it was and then my final excuse (legitimate) has been “I just can’t learn anything unless I have a reason to”.
I’ve finally had a reason/excuse to write a little something in Go, unfortunately it’s at work so I can’t share it here, but for my benefit at least I am noting some of my findings here.
- gore. Use it.
:=is declaration and assignment,=assignment only (thing must already exist).-
When doing
FindStringSubmatch()regex stuffmatch[1]gets what is in the group defined inregexp.MustCompile()as opposed tomatch[0]which is the whole thing. E:g:aString := "matchthefollowing: bit10" re := regexp.MustCompile(`matchthefollowing: ([0-9a-zA-Z]+)`) match := re.FindStringSubmatch(aString) // match[1] will return "bit10" - When building Go programs, even what seems like a warning will stop it building, so if doing little things locally it’s worth doing a
go build && ./thingbuiltas otherwise you’ll wonder why all the changes you are making are having no effect. logvsfmt:logdoes timestamps.log.SetOutput(os.Stdout)to log to stdout.- There is just one loop, a
forloop, but it’s pretty flexible. fmt.Printf("%+v", thing)to see the structure ofthing, much more useful than doing afmt.Println(thing).- There is a built-in
appendfor adding elements onto a slice (A slice is basically the array you expect it to be, although they have something else called an array which you probably won’t use much; And they like to be opinionated about stuff… ha!). There is no built-indelete, but there is a nifty trick you can use to delete an element from a slice:append(aSlice[0:i], aSlice[i+1:]...)will delete element at positionifromaSlice. -
Go is, to my ignorant levels of knowledge, actually fairly simplistic and just gives you the building blocks to make things (so like
c).structs are used a lot for anything not out of the box. I.e. to use a tuple you’d first define astruct:type myTuple struct { elementOne, elementTwo string } // Can then use this in a slice like so: append(aslice, myTuple{"thing", "anotherthing"}) -
structs are also used for Jsonsomejson := []byte(`{"key":"value"}`) type JsonStruct struct { Key string } var somedecodedjson JsonStruct json.Unmarshal(somejson, &somedecodedjson) // somedecodedjson will now look like this: // main.JsonStruct{ // Key: "value", // } - Use capital letters to “export” stuff from the struct. I.e. so we can do
somedecodedjson.Key. -
And this extends to nested json (note use of tags to get specific fields; no space between
json:and"key1"is important):somejson := []byte(`{"key1":"value1", "nestedkey":{"key2":"value2"}}`) type Parent struct { Key string `json:"key1"` Child struct { ChildKey string `json:"key2"` } `json:"nestedkey"` } var somedecodedjson Parent json.Unmarshal(somejson, &somedecodedjson) // Can access values like so... somedecodedjson.Child.ChildKey - Cross compiling is super useful. I.e., being able to do
GOOS=linux GOARCH=amd64 go buildon OSX and then upload the binary to a server. - As long as you don’t use cgo.
That’s all I’ve learnt so far.