Learning Go

I have an idea, so I’ve decided to learn Go as a way of piggybacking the idea. In this case, if the idea doesn’t pan out, I at least learned Go in the process.

I’m starting by taking the tour on the Go website. It has an interactive “playground” aside the walkthrough, so you can write, run, and see results of your Go code. So far, I really like that exports are specified by case, type is inferred, and you only need one type when multiple arguments are the same type. I also like that switch statements without a condition can be used as a cleaner alternative to long if chains and the defer statement can be used to execute functions after a function returns a value. I don’t have a specific use in mind for this, but it sounds useful.

Up until this point, I was smooth sailing, but as soon as the tour started diving into slices and pointers, I looked like the math meme and needed to remind myself that I went to art school. At first, it was paralyzingly computer science-y for me, but then it clicked and now I get it. Pointers are simply references, but you need to be explicit about it or else your changes won’t affect the original instance. (For any folks who can’t believe I don’t know much about pointers, keep in mind I learned code through Geocities, View Source, and Stack Overflow)

In Go, arrays are fixed length, so you end up needing to use “slices” to represent portions of an array, and you can use the make function to create dynamically-sized arrays/slices. There’s also a handy range function that lets you iterate an array/slice by simply writing for i, v := range mySlice. I’m proud of myself for being able to complete the exercise at the end without a CS degree.

Now, I’m learning about “Maps”, which are like objects in JavaScript or hashes in Ruby. Go maps have a handy two-value assignment feature built in, so you can get a value and check if a key has a value in a one-liner: v, ok := m[k], where ok is the boolean of whether it exists.

Functions in Go are pretty much the same as everywhere else, including the ability to have closures. The section ended with an exercise to create the fibonacci sequence, which let me finally use the defer statement to increment the index after returning the value. It probably wasn’t necessary, but I wanted to use it.

So this is interesting. In Go, there are no classes, but a function can be a “method”, which means it has a “receiver” argument. This essentially lets you call the method from that “receiver” (or instance), like String.prototype.myMethod in JavaScript (but you should never actually do this in JavaScript). Go actually prevents this kind of patching by requiring the receiver type to be in the same package as the method. Smart!

Interfaces in Go are similar to elsewhere, but they implement implicitly, so you don’t need to specify that a certain type implements an interface—it just works. One interesting part is that a nil receiver that implements an interface can still have methods called from it—there’s no exception when this happens. One of the most common interfaces is called a “Stringer”, which lets you output types as strings (think .toString() in JavaScript or .to_s in Ruby).

Another cool thing about Go is that functions can return a second value that’s an error, which can be checked when calling the function (e.g., v, e := myFunc()). If the error is nil, the function succeeded. The error exercise has probably confused me the most so far. Apparently, you need to cast the value as an error and Go will automatically call its .Error() method. I still need to wrap my head around types as error types, like the ErrNegativeSqrt type it has you create as a subtype of float64.

I’m really struggling through this exercise about “Readers”. I get it at first, but by the time we get into bytes, I realize my eyes are stinging because I’ve forgotten to blink. I understand what the exercising is asking of me, but I’m not well-versed enough to complete it yet. I’ll come back to it—maybe.

Though it’s unrelated to my idea, the section on images really piqued my attention. I’ve had some fun with image manipulation in the past with ImageMagick, but never actually built anything worthwhile since it’s pretty heavy on Ruby. In Go, however, it might be much more efficient. The exercise itself froze me for a minute, as it was unclear whether I had to create my own image interface or simply create a struct that implements the interface—it was the latter. Beyond the exercise goal of generating an image, I went further by adding width and height properties to my struct to see how I could control the bounds of the image. That worked as expected.

I’m now at the last section of the tour, “Concurrency”, which starts with “Goroutines”... I might take this opportunity to Homer Simpson into the bushes and cook dinner.

Okay, so Goroutines seem pretty powerful. You can essentially run code in its own thread, hence the name of the section, “Concurrency”. Go also has “Channels”, which let you send and receive values between Goroutines. They’re surprisingly intuitive—simply follow the arrow (e.g., c <- v sends the value to the channel and v := <-c receives the value from the channel). You can also use range on a channel to loop through received values until the channel closes. Again, very smart!

Oof. I’m now at an exercise that has me walking a binary tree. This feels like a job interview that I’m woefully unprepared for. I understood the first part where I walk the tree and print the values, sending each value through the channel, but writing the Same function is a no go for me. I really wish the Go tour had a hint feature when you get stuck. I’m going to move on. Also, I didn’t get the job.

Next up, the “Mutex”, which I first mistook as “Codex” ...from Assassin’s Creed. It looks like these provide a safe way of changing values without a race condition. The concept is self-explanatory, which is a relief after a few of these lessons. The final exercise is to parallelize a web crawler without fetching the same URL twice. Thankfully, this was a piece of cake from start to finish, so I’m not completely limping away from this experience.

Oh, look—I finished the tour, and it’s now nighttime. Unfortunately, I didn’t even touch the idea I had at the beginning of this post, which I have expected would happen, but at least I learned Go!