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
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
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
}
You can define a struct in order to manage your data easily.
type human struct {
firstName, lastName string
}
type dog struct {
name, breed string
}
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"
}
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"}
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())
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
}
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
}
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)
}
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)
}
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)
}
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)