Golang for Rubyists. Part 6. Structs, Methods and Interfaces
Let the force be with you, my friends. Today we will dive into some of the features, statical typing brings to us, those are Structs and Interfaces.
Structs
As I aim my series of articles to those, who has mostly scripting languages background, such as Ruby, Python, JS, I would expect that you have a very brief understanding what those things are. In the best case, you remember that words from your Computer Science study in a university. Let’s jump right into the code and take a look at some Struct definition example:
(https://play.golang.org/p/FEQVAtNYig7)
Doesn’t it look similar to:
By me, it looks pretty much. But as you may know, Ruby also has structs. Just because it is not statically typed we have two different structs, OpenStruct and Struct. And even the second one is still not as strict as Golang’s one, because it doesn’t have a type check. Anyway, the same snippet using Ruby’s Struct would look like this:
Uh, I love Ruby’s expressiveness and readability. Go is quite more verbose, but as you may notice, it is pretty readable as well. What else should we add to understand structs? I think it should be clear enough from the example. Struct is basically a combination of one or more named fields with specified types. Fields can be accessed using dot (.) for both reading and writing.
Methods
Let’s take a look at one more Ruby example, which uses Struct:
How to implement something similar in Golang? Easy-peasy!
(https://play.golang.org/p/RTaUjMnUXF6)
Could you ever imagine it? It looks exactly the same as Ruby’s methods. And even the name is exactly the same, Methods! So, the method in Golang is a function, which related to some specific Struct and can be applied only to it (only? hmmmm)
Interfaces
Do you remember, what polymorphism is? Wiki says:
Polymorphism - the provision of a single interface to entities of different types
.
And how do we achieve it with Ruby? Eh, actually multiple ways, this Thoughtbot’s article perfectly describes them. But in general case, Ruby has a duck typing system, so let’s take a look on the following example:
We have a class AutoFeeder which method expects something, which can be feeden (so, something, which implements interface “feed”). And since we’re in Ruby, we don’t have type checks, so we can just pass any object into this method and it either will perform the feeding operation or will fail with famous NoMethodError. And how can we achieve the same in Golang? As you remember, you should always specify a type for a function, so this snippet will work out:
But how to make it work for my poor hungry kitten as well? Can we just pass my cat into feed_animal function?
Ah, c’mon, ruthless static typing! prog.go:33:14: cannot use &myHungryKitten (type *Cat) as type *Dog in argument to feed_animal
Thank gods, we have Interfaces! Let’s first take a look onto the example and then I will explain everything.
Just like that! Now both my pets are full and happy now, many thanks to Interfaces! So, I changed to things here.
Firstly I added an interface, named Animal. You see the syntax is very similar to the way you describe structs. But instead of defining attributes, you specify, which methods should the particular struct implement, in order to comply with this interface.
The second thing I changed is now feed_animal
expects not a Dog pointer, but some struct, which implements the interface Animal.
(https://play.golang.org/p/8NlLiCZDr-R)
Few important things to mention about Interfaces in Golang.
- Structs don’t have to explicitly specify, that they implement some interface. It is checked implicitly by the interface itself.
- One struct may implement multiple interfaces. Actually, interfaces topic is deeper than what I described in this article, but this information should be totally enough to understand them and to start using it. Also, I hope methods and structs are clear for you now as well. Feel free to ask questions in the comments section or approach me via Twitter. Or even buy me a coffee ^__^ Good luck in your endless but immersive learning path!