DEV Community

Cover image for I fell in love with Go!
Adnan Babakan (he/him)
Adnan Babakan (he/him)

Posted on • Updated on

I fell in love with Go!

Hey there DEV.to community!

It's been a while that I've started learning Go (GoLang) and after trying Go I wanted to write this article and share my experience with you about the path I had to go thru.

Go is an open-source programming language supported by Google and is one of the most different and magnificent programming languages out there.

These are the things I loved about Go:

It is both statically-typed and dynamically-typed

Well, this was strange! Although Go claims to be a statically-typed language, some of its features make it seem like it is dynamically-typed.

The normal way of declaring a variable in Go is as below:

var myAge int8 = 18
Enter fullscreen mode Exit fullscreen mode

Which, as you can, has int8 declaring its type.

There is a shorter way of declaring values without the need of explicitly defining the type of the value that is going to be assigned to the variable using the := variable as below:

myAge := 18
Enter fullscreen mode Exit fullscreen mode

The := operator gives you the power of dynamic types in a statically-typed language.

Very fast in the compilation

Go is a compiled language and is very fast in the compilation.

Go provides you go build and go run to build or build run without a compiled file respectively.

go run runs your program fast enough that you might think Go is not even compiling and is just interpreting it!

This is a very good point about a compiled language so you can debug your code really fast.

When you compile your Go code it gets compiled to machine code directly depending on the CPU's ISA so the compiler running on so your app runs really fast!

Interfaces and structs

Interfaces and structs are really interesting for me, they make your code more flexible and are really beautiful to use.

Interfaces and structs are playing the role of classes in other programming languages, put it this way.

You can define an interface just as simple as this:

type creature interface {
    getFullName() string
    getType() string
}
Enter fullscreen mode Exit fullscreen mode

You can define a struct in order to manage your data easily.

type human struct {
    firstName, lastName string
}

type dog struct {
    name, breed string
}
Enter fullscreen mode Exit fullscreen mode

Let's define how our functions that are going to handle the functions defined in the creature interface.

func (h human) getFullName() string {
    return h.firstName + " " + h.lastName
}

func (h human) getType() string {
    return "Human"
}

func (d dog) getFullName() string {
    return d.name
}

func (d dog) getType() string {
    return "A " + d.breed + " dog"
}
Enter fullscreen mode Exit fullscreen mode

As you can see each struct type can have its own methods to be called from the interface.

Now let's create some instances:

var me creature = human{firstName: "Adnan", lastName: "Babakan"}
var myPet creature = dog{name: "Max", breed: "German shepherd"}
Enter fullscreen mode Exit fullscreen mode

Now, these two variables are created and you can use getFullName and getType methods on both of them like below:

fmt.Println(me.getFullName())
fmt.Println(myPet.getType())
Enter fullscreen mode Exit fullscreen mode

Pointers

Go is a pass-by-value language which means every time you pass a variable to a function in Go, its value is intact and Go only uses its value to do some processes.

See the code below:

package main

import "fmt"

func test(n int32) int32 {
    n += 10
    return n
}

func main() {
    var a int32 = 2
    fmt.Println(test(a)) // 12
    fmt.Println(a) // 2
}
Enter fullscreen mode Exit fullscreen mode

Your a variable is intact, its value is only used and not changed.

Now, this can be changed by using Go's pointers and addresses features.

In order to get the address of a variable, you can use & in front of the variable.

func main() {
    var a int32 = 2
    fmt.Println(&a) // Shows something like 0x40e020
}
Enter fullscreen mode Exit fullscreen mode

And in order to get the value that is stored in an address, you can use the * symbol in front of a variable storing the address.

Let's change the sample a little bit:

package main

import "fmt"

func test(n *int32) int32 {
    *n += 10
    return *n
}

func main() {
    var a int32 = 2
    fmt.Println(test(&a))
    fmt.Println(a)
}
Enter fullscreen mode Exit fullscreen mode

In this code, I've passed the address of the variable a by using the & symbol and retrieved its value by using * in my test function. Keep in mind that 8 in front of a data type means that it's going to be an address keeping this data.

The defer keyword

This is another great feature of Go. defer keyword helps you run a function at the end of the current function.

Look at the code below:

package main

import "fmt"

func test(n *int32) int32 {
    defer fmt.Println("Calculation done")

    fmt.Println("Not started yet!")
    *n += 10
    return *n
}

func main() {
    var a int32 = 2
    fmt.Println(test(&a))
    fmt.Println(a)
}
Enter fullscreen mode Exit fullscreen mode

The test function will run all the codes then the line that is starting with the keyword defer.

This can really be handy when finishing some function, which instead of adding codes just before return keyword, you can do this.

(For those who are new to programming: it is not possible to write any code after the return keyword in a scope)

Multiple returns

This might be new for some people, but Go supports multiple data to be returned.

Having the code below:

package main

import (
    "fmt"
    "math"
)

func calc(n float64) (float64, float64) {
    return math.Pow(n, 2), math.Pow(n, 3)
}

func main() {
    var toThePowerOfTwo, toThePowerOfThree float64
    toThePowerOfTwo, toThePowerOfThree = calc(2)

    fmt.Println(toThePowerOfTwo)
    fmt.Println(toThePowerOfThree)
}
Enter fullscreen mode Exit fullscreen mode

You can see that my calc function has two returned data which are respectively placed in the variables named toThePowerOfTwo and toThePowerOfThree.

This is amazing when dealing with complex functions that you want them to have multiple results returned.

Powerful garbage collector

Garbage collection is a very important matter when designing apps. Unlike so many other languages you don't need to free up the memory by pointers. Go has one of the best garbage collectors out in the programming universe.


If you are a Go programmer tell me what you love about this little cute blue gopher. And correct me if I'm wrong about anything listed above.

Top comments (0)