10 Practical Tips for Writing Golang Applications

"Go is an open source programming language that makes it easy to build simple, reliable, and efficient software."

The phrase above that you can find on golang.org is a perfect summary of a programming language that fills a huge gap in the software industry. Due to its simplicity, performance and user-friendliness, Go quickly became one of my favourite programming languages. There aren't too many languages out there that you can build a web server with a few lines of code after all:

package main

import (

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Go is amazing %s!", r.URL.Path[1:])

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))

Go is Strongly Typed

Go, not only reduces the amount of code you have to write, it also supports pointers and it's a strongly typed language. The types of every object must be known at runtime:

var distanceUnit string = "m"
distance := 200

var ptrPerson *Person
ptrPerson.walk(distance, distanceUnit)


Gofmt allows you to focus on the code instead of the indentation or style of it using a single command:

go fmt path/to/your/package

Standard Packages

Standard packages/libraries have pretty good support for most things you need so you won't need to search for third party packages.

Single Executable

Go applications compile into a single executable binary that makes life much easier for developers. Also, this simplifies the distribution of software and allows containerization (Docker, etc.) of services.

Dep (Dependency Manager)

A popular but non-standard package manager that enables us to keep track of the versions of the packages we use in our application. Here is a well-written how-to guide

Go uses Slices (Dynamic Arrays)

Slice is a very convenient dynamic array. Here is how to perform some operations on Slices:

// Iterate over slice
for i, v := range s { // use range, inc order
 // i - index
 // v - value
for i := 0; i < len(s); i++ { // use index, inc order
 // i - index
 // s[i] - value
for i := len(s)-1; i >= 0; i-- { // use index, reverse order
 // i - index
 // s[i] - value

// Function argument
func f(s []T) // s - passed by value, but memory the same 
func f(s *[]T) // s - passed by refernce, but memory the same 

// Append
a = append(a, b...)

// Clone
b = make([]T, len(a))

// Remove element, keep order
a = a[:i+copy(a[i:], a[i+1:])]
// or
a = append(a[:i], a[i+1:]...)

// Remove element, change order
a[i] = a[len(a)-1] 
a = a[:len(a)-1]

Memory management with pools of objects

We can use thread safe pools to collect objects for reuse:

var p sync.Pool
var o *T 
if v := p.Get(); v != nil {
 o = v.(*T)
} else {
 o = new(T)

// use o

p.Put(o) // return to reuse

Close Channel to Notify Multiple Listeners

Closing a channel will notify all the readers on that channel:

c := make(chan int)

for i := 0; i < 5; i++ {
 go func(i int) {
  _, ok := <-c
  fmt.Printf("closed %d, %t\n", i, ok) // random order


We can inherit the properties, methods of a struct by embedding it into another struct:

type A struct {
 Id int
 B // embed B struct

Concatenating and Building Strings in Go 1.10+

With the arrival of Go 1.10. It's now possible to use String Builder to create strings in an efficient way:
import (

func main() {
 s := "Hello "

 log.Println(join(s, "World"))

func join(strs ...string) string {
 var sb strings.Builder
 for _, str := range strs {
 return sb.String()

Variadic Functions

Variadic functions can be called with any number of trailing arguments:

func variadicFunc(anotherArg int, args ...string) ([]string, int) {
 var arr []string
 for _, s := range args {
  arr = append(arr, s)
 return arr, anotherArg

func main() {
 fmt.Println(variadicFunc(129471294, "1", "2", "3")) // ["1","2","3"]

That's all for now, feel free to leave a comment below, if you have anything to add or ask. Thank you and happy coding!

Software Developer, Codemio Admin

Disqus Comments Loading..