Go (GoLang) Programming Language from a C#/Java perspective? Is it worth the switch?

As most of you’ve heard, Go is the new programming language(Maybe not so new anymore) being actively developed by Google. Being a new actor on the scenes, it’s becoming more and more popular. We’ve took a decision to give it a try few months ago and implemented one of our projects in pure Go. I’ll try to share the nice things I’ve liked about it, the pain points and will try to share my knowledge to make it easier for you to decide if you should switch to it or not. Let’s start with the biggest difference with everything else you know:

Go isn’t your typical object oriented programming language

Yes, Go is supposedly have objects, and methods running on those objects, but if you’re expecting a object oriented language where there’s layers and layers of abstraction, you’re at the wrong place. Go supports simple object hierarchy but that’s about it. There are things called “Interfaces” but they are more like promises on the signature of an implementing object. You can pick multiple interfaces and implement them but that doesn’t mean your object belongs to those. Multiple interfaces might have same methods with same signature and that’s totally fine. Because again, they only define the signature. So let’s say you have two interface defining Sum(int, int), you can’t have two definitions in your object like you do in C#. In C#, depending on the type of the interface you’re holding a reference to, you’ll be calling different implementations at the run time. In Go, it’s a pure method name and signature match.

What happened to our best friend called “Method Overloading”

Another bad news, there’s no overloading(Of course you can do tricky things like accepting an interface{}… which accepts any number of arguments and then use reflection to check them but please don’t!). You need to say goodbye to your old thinking of defining Sum(int, int), Sum(float, float) and etc. You’ll see a lot of methods with notations like SumI(int,int), SumF(float,float).

Async Programming

If you’re used to the async/await notation in C# then you probably won’t be impressed by Go’s capability of parallelization. But for Java developers who’s having a hard time on async programming, good news. In Go, you can make a method async fairly simple(Just follow some rules to make sure it’s thread safe) and then you just call it with the word “go” like “go hello()” and that’s it. It’ll run async. I won’t go into details of channels and etc. as this is not a post about learning Go.

What about exceptions

There’s nothing called exceptions. Yes, you heard me right! There’s a similar concept called panic/recover and if you’re curious about why it’s called panic because you literally panic. It’s a change in the way you are thinking. You don’t panic when there’s something going wrong, you panic when everything is terribly wrong. Panics are assumed to be the things that are never expected and shouldn’t happen at all. That why you panic!

Then how do you handle unexpected situations?

Good question. Well, go supports multiple variable returns. So you can return as many variables as you’d like. So most of the times you’ll see the signature of the method being like “Divide(float, float) (float, error)”. This means method Divide will return you the result and also an error object. So if anything went wrong, error will be set to what happened. If everything is fine, it’ll be “nil”.

Doesn’t checking error at every return makes code look ugly and repetitive checks?

Go designers must have realized the code is getting out of control and then find a solution to do assignment and checks inside “if” checks and etc. It’ll look something like:

And yes, this make the code quite clean, quite neat and easy to read. And the scope of the variable “err” is only the if statement. So you don’t need to worry about defining too many objects going forward.

Why did you use “:=” instead of “=” ?

Welcome to the new assignment operator introduced in Go. You can either use an equal(=) sign to do assignment into an already defined object, or use colon-equal(:=) to define and then assign a value to a variable. And you don’t need to specify the type of the variable. Go is smart enough to figure out the type on the right side of the assignment and then define the variable on the left accordingly at compilation time.

Did you say type definition at compilation time?

Yessss. This is one of the parts I love about Go. It’s strong typed. So if your code is being compiled, that means you didn’t make some small assignment mistake that’ll take you hours to find that you face in typeless languages like Javascript.

Talking about compilation, how does it deal with dependencies?

And here goes my second favorite thing about Go.  It’s designed to solve dependency problems. So every code you write and everything you depend on is statically linked during the compilation process into a single executable. So if you have your “AwesomeSoftwareWithAllDependencies.go” file, that means chances are it’ll run with no problem!

What’s the thing you hate the most?

Well, being a new language, the community and help pages aren’t that great. Sometimes you spend hours and hours trying to solve a really simple problem because there’s no examples to take a look. And even though Google is good at designing things, I can’t say documentation is one of their strengths. They want you to feel like a hacker almost every time. Here’s an example from one of the methods I wanted to use in Google App Engine:

There’s no examples, no additional notes. I find it quite useful to learn a method called “ModifyLease” actually “modifies the lease” 🙂

Anything else you don’t like?

Namespaces

There can’t be more than 1 namespace per directory so usually namespaces comes from the directory names. So if you’re in a directory called “math”, the namespace will be “math”. There’s no difference between having 10 code files vs 1 in the same directory. Go basically appends all your code files in a directory to a single one before compiling. All the variables are inside the same namespace(which is kinda equivalent of the classes in other languages) are visible from all the files.

First bug we had with append()

One of the weird bugs we’ve had was the use of the append() method. In go, all arrays you use are static sized arrays. Then there’re slices implemented on top to get a slice of an array. If you want a dynamically resizing array then you define a slice and use the append() method like;

From the usage, it’s easy to get confused and forget the part that append() method actually adds item to the end of the slice if there’s empty space available. And if there isn’t then it copies all the items to a double sized array and returns a pointer to the new array(It’d have been much simpler if it accepted a pointer and always returned the latest one but anyways..). So we had a problem when append was sometimes returning a new pointer and sometimes just writing to the same array and it was really hard to debug.

Second bug we had with append()

And again with append() method, if you are a performance freak and want to avoid the costly copies and just want to give an initial size to your array, you can’t! Let’s say you define it as;

The problem is append actually appends these two strings as the 3rd and 4th items. So if you wanna give the array size in advance, you need to manually access to elements with an index like;

You said not much object orientation, how do you make things private/public?

There’s another thing you need to get used to here. Upper case things are public, lower case things are private. I’ve spent almost few hours trying to figure out why my datastore object isn’t saving any data I put into it. Turns out I’ve defined the variable with a lower case like “firstName” and it was not visible by the datastore package that tries to see the members by reflection.

Cross Compatibility ?

I think this is another strength that Go has. It can run virtually anywhere. It supports all major operating systems.

Is there a good IDE for it?

I’m using WebStorm from IntelliJ with the Go plugin and it’s working great. I’m getting all my intellisense auto completions and everything else you’d expect from an IDE.

Give me the juice? What is your choice?

Go does come with most libraries you need to build a REST API(JSON and etc.) and really easy to ramp up on and implement backends to process requests. It’s quite fast, strong typed and definitely growing more and more. So if you need to build something on Google App Engine in few days and make it process heavy loads of information, I think it’s the best choice. The setup time is literally few hours to get your project set up and working. And Google provides nice scripts to easily deploy your app with one command and so easy to run it locally as well. And it’s so easy to make a server application and start it listening to some port almost in no time. So you can even deploy it to your VMs and etc. pretty easily. But if you need to build a project that’ll be used for a long period of time and you need real object hierarchy and etc. please do stay away from Go. Unless you already have a big library of Go packages and wanna use them.

A good starter?

There’s an interactive tutorial directly on the golang website that is reachable by: https://tour.golang.org/welcome

Leave a Reply

Your email address will not be published. Required fields are marked *