Golang — Building Blocks

Ranjeet Kaur
5 min readJun 17, 2018

In this article we will delve into the details about programming in Go. We have already covered Installation and setup in the previous article.

Go is a statically typed, procedural language, similar to C. It is simple to write and understand, but as your code gets more complex, it needs to be organized well to remain maintainable.

One by one, we will go into details of how a Go Program is structured.

Packages : A Package in Go is nothing but the collection of code of all the files in the same directory. It is defined at the start of your Go file.

package buildingBlocks

You can have multiple Go files in the same directory, but all of them need to have the same package name. As for files in sub-directories, they can have a different package name from the parent directory, but again they need to have the same package across the sub-directory.

Libraries : As a great coder once said -

“Code Reuse is the Holy Grail of Software Engineering”

What makes any language great is the amount of reusable solutions available in the form of third party libraries. To import any library into your code, you need to first download it and then add it to your code.

To get started, you can download any library into your system, using the following command:

go get -u <Library Path>Example:
go get -u github.com/sirupsen/logrus

Of course, nobody expects you to manually download each and every library you need. You can use Go Dep (Go 1.9 or above) or Go Mod ( Go 1.11 or above) for dependency management.

Imports : Next step is to import the dependency into your code. For that, you can add following snippet after package declaration.

import "github.com/sirupsen/logrus"

If you have multiple imports, you can either add them individually (as shown above) or group them into a block.

import (
"github.com/sirupsen/logrus"
"fmt"
)

For locally added code, you can import it using it’s fully qualified name, from the repository location($GOPATH/src). Ex: If you have a Go file at location:

$GOPATH/src/tutorials/BuildingBlocks/importSamples/default/test1.go

You can import this package as follows.

import (
"tutorials/BuildingBlocks/importSamples/default"
)

You can also use relative paths in imports, if you are using Go Modules. (More on that later)

Following are a few pointers for configuring imports -

1. Using Functions from Imported Packages : By default, when you import a dependency, you can call its functions in the following manner :

package mainimport {
"go-go-golang/BuildingBlocks/importSamples/default"
}
func runImportSamples(){
defaultPath.Foo1()
}

2. Importing an unused dependency: For the cases where you want to use initialization from a dependency, without accessing any functions, you can simply add an _ (Underscore) in front of your import path. This will ensure that the pkg is initialized and Go will not give compilation error for it. Ex :

package mainimport {
_ "go-go-golang/BuildingBlocks/importSamples/ignoredPath"
}

3. Naming an imported dependency : To make your code more readable, Go allows you to name your imports, so that you can use functions/structs from an import, through custom names.

package mainimport {
NP "go-go-golang/BuildingBlocks/importSamples/namedPath"
}
func runImportSamples(){
NP.Foo3()
}

4. Not Naming an imported Dependency : Sometimes you might not want to have any prefix to your function calls. Go gives you provision for that as well.

package mainimport {
. "go-go-golang/BuildingBlocks/importSamples/unNamedPath"
}
func runImportSamples(){
Foo4()
}

Note: If you have two unnamed imports, having the same method, Go will give compile time error if you try to call that function.

Variables : Variables in Go can either be primitive like (int, in8, int32, int64, string, float, etc) or structs types. You can declare a variable in Go as follows.

var name1 string = "JohnDoe1"

Similar to most functional languages, in Go, you don’t always need to give type when declaring a variable. You can directly set the value and type will be inferred as per the value.

var name2 = "JohnDoe2"
name3 := "JohnDoe3"

To define a constant variable, you can prefix the declaration with key word const.

const NAME = "NAME"

and you can also group multiple constants together.

const (
FIRST_NAME = "FIRSTNAME"
LAST_NAME = "LASTNAME"
)

Variable Scopes: Scope of a variable is set based on where the variable is declared and the case of its first alphabet. For a variable declared inside a function, scope is limited to that function. For a variable declared outside any function or struct, it is accessible outside the package, if first letter of the variable name is capital, else it is accessible only inside the package where it is declared.

Structs : Similar to C and C++, Go allows you to group your data in the form of structs. You can define a struct as follows:

type sampleStruct struct {
Name string
}

Or you can club multiple structs in one block.

type (
sampleStruct1 struct {
Name string
}
sampleStruct2 struct {
Name string
}
)

Variables in a struct can either be private, i.e., accessible only in the same package, or public, i.e., accessible across packages. In go, scope of a variable is determined by the name of the variable. If the variable name starts with a small letter, it is considered private, and if it starts with a capital letter, it is considered public.

Functions : Like any other programming language, functions in Go are used to group some code for reusability. It can take one or more parameters as input. Biggest difference between functions in Go and functions in any other language is that, functions in Go allow you to return more than one output. Following is an example of a function in Go which takes two inputs and returns two outputs.

func format(name string, age int64) (string, string) {
return "Name : " + name, "Age : " + strconv.FormatInt(age, 10)
}

Values returned from a go function can be set to variables, as follows.

name, age := format("JohnDoe", 25)

Function Scopes: Similar to variables, functions in Go can either be private, i.e., accessible only in the same package, or public, i.e., accessible across packages. Scope of a function is also determined by the name of the function. If the function name starts with a small letter, it is considered private, and if it starts with a capital letter, it is considered public.

Parameters passed in go functions can be passed by value:

func formatAge(age int64) (string) {
return "Age : " + strconv.FormatInt(age, 10)
}

Or by Pointer:

func formatName(name *string) {
*name = "Name : " + *name
}

Call by pointer, can be made as follows.

name := "JohnDoe"
formatName(&name)

These are the basic modules of a typical Go Program. Code Samples for this tutorial can be accessed through GitHub Repo.

I hope you find it helpful. If you have any suggestions, please feel free to drop a comment.

In the Next Article, we will discuss more details of coding in Go.

--

--