Golang: A Systems Programming Open Source Language by Google

1
8287

Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language. Go, often referred to as Golang, is an open source programming language created at Google in 2009 by Robert Griesemer, Rob Pike, and Ken Thompson.

Google describes its plans for Go in one of its blog posts as, “We’re hoping Go turns out to be a great language for systems programming with support for multi-processing and a fresh and lightweight take on object-oriented design, with some cool features like true closures and reflection. Go attempts to combine the development speed of working in a dynamic language like Python with the performance and safety of a compiled language like C or C++.”

This astounding language is meant to be simple-to-learn, concise and easy-to-read by other developers. It offers an expressive type system, as well as fast compilation, good performance and built-in language features that simplify concurrency. Go is reminiscent of C in its syntax, making it relatively easy for long-time C developers to learn. It uses interfaces as the building blocks of code reusability. Golang is a compiled language that supports static linking, and Go code can be statically linked to a native binary and be deployed in cloud servers easily, without worrying about dependencies.

Go, which provides a rich standard library, is designed primarily for systems programming. Its credentials are unsurpassed. Go provides type safety, garbage collection, dynamic-typing capability, many advanced built-in types such as variable length arrays and key-value maps, etc.

Why Go?

Go is recommended for the following features:

  • It is simple, concurrent and has good cross-platform support.
  • Go is awesome for microservices. Microservices designed with Golang are easy to modify, debug and test. You can change one service without impacting the entire functionality, and can quickly change the design and add new functions.
  • Golang can be used for server development. It is a general-purpose language that is suitable for many things including server side Web applications, distributed apps, DevOps, etc. Currently, Docker is probably the most successful, well-known container platform. Google is also building Kubernetes, a Docker competitor using Go. Many big companies including Google, Dropbox, Soundcloud, Cloudflare, etc, use it for their projects.
  • The use of Go for enterprise development has become a trend. For example, Netflix uses Go for exactly this purpose. Another reason is its efficient data processing on servers and optimised server loading. Golang enables non-disruptive background loading.

Go does have a few drawbacks, though, which are mainly in graphical and machine learning. It has become more prominent after many blockchain platforms started using it for development.

Installation

Golang is supported on all the three platforms — Mac, Windows and Linux. You can download the binary for the corresponding platform from https://golang.org/dl/.

In Linux, download the tar file from https://golang.org/dl/ and unzip it to /usr/local to create a Go tree in /usr/local/go. For example:

tar -C /usr/local -xzf go1.4.linux-amd64.tar.gz

Add /usr/local/go/bin to the PATH environment variable, as shown below:

export PATH = $PATH:/usr/local/go/bin

For installing Go in Ubuntu, run the following command:

sudo apt-get install golang

After the Go installation is done, you can check the version by using the following command:

go version

Programming with Go

Some of Google’s sample Go code reveals that the syntax is C-like. It incorporates functions, decision making and loop control statements, standard conditional expressions and many other features that you’d expect to find in a C-like language, but with a handful of nice twists. There are some Python-like features too, including array slices and a map type with constructor syntax that looks like Python’s dictionary concept but eschews some typical object-oriented programming concepts such as inheritance.

A Go program can vary in length from three lines to millions of lines, and it should be written into one or more text files with the extension .go. For example, hello.go.

Vi, vim or any other text editor too can be used to write a Go program into a file. Ensure the Go compiler is in the path and that it is being run in the directory containing the source file hello.go.

Our first Go program: first.go

To begin, give the following commands:

package main

import “fmt”

func main()

{

fmt.Println(“Hello World!”)

}

Compile it and run it using the go run command:

go run first.go

Here is the output:

Hello World!

Here is a brief explanation of what each line does in the program.

package main: This is the first line of the program and defines the name of the package in which this program lies. It is a mandatory statement, as Go programs run in packages that provide code reusability.

import fmt: This is a preprocessor command, which tells the Go compiler to include the files in the package fmt.

func main(): This is the main function where the program execution begins.

fmt.Println(): The fmt package has exported the Println method, which is used to write text to the standard output. P is written in upper case. In the Go language, if a name that starts with a capital letter is exported, it implies that the function or variable/constant is accessible to the importer of the respective package.

Tokens in Go

Tokens are the building blocks of any programming language and consist of keywords, identifiers, variables and constants. There are 25 keywords in Golang and some of the reserved words are: break, chan, defer, fallthrough, go, map, package, var, type, interface, etc. An identifier in Go starts with any letter from A to Z or a to z or an underscore (_) followed by zero or more letters, underscores, and digits 0 to 9.

Data types in Go

The following are the basic data types available in Go:

1. Boolean types that consist of the two predefined constants — (a) true, and (b) false.

2. Numeric types that are again arithmetic types and represent integer types or floating point values throughout the program. The predefined architecture-independent integer types are: int, int8, int16, int32, int64 (signed integers) and uint, uint8, uint16, uint32, uint64 (unsigned integers), float32 and float64.

  • int: This represents 32- or 64-bit integers, depending on the underlying platform. Size and other details are the same as that of C language.
  • Other numeric types include byte and rune. The former is an alias of uint8 and rune is an alias of int32.

3. String types represent the set of string values. Its value is a sequence of bytes. Strings are immutable types, the contents of which cannot be changed once created. The pre-declared string type is string.

4. Derived types, which include pointer types, array types, structure types, union types, function types, slice types, interface types, map types and channel types.

Variable declaration in Go

The var name type is the syntax to declare a single variable. For example: var a int, var b bool, var st string.

package main

import “fmt”

func main()

{

var age int // variable declaration

fmt.Println(“my age is”, age)

}

Since the variable, age, is not assigned any value, Go automatically initialises it with the zero value of the variable’s type. We can declare multiple variables at once, as follows:

var salary, amount int

Go enables us to declare multiple or single variables and initialise them at the same time:

var age, salary = 25, 30000

package main

import “fmt”

func main()

{

var number, amount = 10, 15

var sum = 20

fmt.Println(number, amount, sum) prints the o/p, 10 15 20

}

Go has awesome shorthand for declaring and initialising a variable. The syntax is:

variable := value

number := 10

amount := 15

fmt.Println(number, amount)

Printf can also be used along with the corresponding control strings in Go:

package main

import “fmt”

func main() {

var i int

var f float64

var b bool

var s string

var name = “Ann”

fmt.Printf(“%T %T %T %T\n”,i,f,b,s) // Prints type of the variable

fmt.Printf(“%v %v %v %q \n”, i, f, b, s) //prints initial value of the variable

fmt.Printf(“type : %T & value : %v\n”, name, name)

}

The output will be:

int float64 bool string

0 0 false “ ”

type: string & value : Ann

Decision making statements

1. If statement: An if statement consists of a Boolean expression followed by one or more statements:

package main

import “fmt”

func main()

{

number := 10

if number >= 5

{

fmt.Println(“I will print the value:”, number)

}

}

Unlike in other languages like C, the curly braces are mandatory even if there is only one statement between the { }.

2. If..else statement

package main

import “fmt”

func main()

{

num := 10

if (num > 0)

{ //checks if number is positive

fmt.Println(“the number is positive”)

}

else

{

fmt.Println(“the number is negative”)

}

}

Nested if..else : (Complete using greatest of 3)

package main

import “fmt”

func main()

{

x:= 10 y:=20

if( x >=10 ) {

if( y >= 10 )

{

fmt.Printf(“Inside nested If Statement \n” );

}

}

fmt.Printf(“Value of x is : %d\n”, x );

fmt.Printf(“Value of y is : %d\n”, y );

}

Switch in Go

Switch statements are used to check conditionals with many cases. We can also check multiple expressions by separating them using commas:

number := 10

switch number

{

case 5:

fmt.Println(“The number is 5”)

case 10,20,30:

fmt.Println(“The number is a multiple of 10”)

case 7,13:

fmt.Println(“The number is prime!”)

}

}

Loops

The for loop is:

func main()

{

for i := 1; i <= 5; i++

{

fmt.Println(“Value:”, i)

}

}

Multiple initialisation and increment in a for loop is as follows:

package main

import “fmt”

func main()

{

for no, i := 10, 1; i <= 10 && no <= 19; i, no = i+1, no+1

{ //multiple initialisation and increment

fmt.Printf(“%d * %d = %d\n”, no, i, no*i)

}

}

The syntax for creating an infinite loop is shown below:

for

{

}

Functions in Go

The syntax of function definition in the Go programming language is as follows:

func function_name( [parameter list] ) [return_types]

{

body of the function

}

The function declaration starts with the func keyword followed by the function’s name. The parameters are specified between (‘and’) followed by the returntype of the function. The syntax for specifying a parameter is the parameter’s name followed by the type. Any number of parameters can be specified like parameter1 type, parameter2 type. Then the body of the function block, or collection of statements that define what the function does, is enclosed in { }.

func sumTotal(price, no int) int //if the consecutive parameters are of the same

{ type, we can skip writing the type each time

var total = price * no

return total

}

package main

import “fmt”

func calculateBill(price, num int) int

{

var totalPrice = price * num

return totalPrice

}

func main()

{

price, num := 90, 6

totalPrice := calculateBill(price, num)

fmt.Println(“Total price is”, totalPrice)

}

Function to swap 2 numbers:

func swap(x, y int) (int, int) {

return y, x

}

func main() {

a, b := swap(10, 20)

fmt.Println(a, b)

}

Arrays, slices and maps in Go

Instead of declaring individual variables, such as number0, number1… and number99, you declare one array variable such as ‘numbers’ and use numbers[0], numbers[1], and numbers[99] to represent individual variables. In Go, an array is a numbered sequence of elements of a specific length.

var variable_name [SIZE] variable_type

Eg: var x [10] int //This is the example of array declaration in go

func main() {

var a [2]string

a[0] = “Hello”

a[1] = “World”

fmt.Println(a[0], a[1]) //prints the o/p : Hello World

fmt.Println(a) //prints the o/p : [Hello World]

primes := [10]int{2, 3, 5, 7, 11, 13}

// short hand declaration to create array

fmt.Println(primes) // prints the o/p : [2 3 5 7 11 13 0 0 0 0], remaining elements filled with 0

The Go programming language allows multi-dimensional arrays. The following example prints a 2D array:

func main() {

var twod [2][3]int

for i := 0; i < 2; i++ {

for j := 0; j < 3; j++ {

twod[i][j] = i + j

}

}

fmt.Println(“Elements : “, twod)

}

Slices

A slice is a convenient, flexible and powerful wrapper on top of an array. Slices do not own any data on their own. They are just the references to existing arrays.

The type [ ]T is a slice with elements of type T. A slice is formed by specifying two indices, a low and high bound, separated by a colon:

func main() {

names := [4]string{“John”,”Paul”,”Ann”,”Manu”,}

fmt.Println(names)

a := names[0:2]

b := names[1:3]

fmt.Println(a, b)

O/p

[John Paul Ann Manu]

[John Paul] [Paul Ann]

Maps

Go provides another important data type named the map, which maps unique keys to values. The declaration is as follows:

/* declare a variable, by default map will be nil*/

Syntax : var map_variable map[key_data_type]value_data_type

Eg: var namedepartment map[string]string

You must use make function to create a map.

Syntax : map_variable = make(map[key_data_type]value_data_type)

Eg : namedepartment= make(map[string]string)

package main

import “fmt”

func main() {

personSalary := make(map[string]int)

personSalary[“Liz”] = 12000

personSalary[“Amy”] = 15000

personSalary[“Mike”] = 9000

fmt.Println(“personSalary map contents:”, personSalary)

}

Prints the o/p:

personSalary map contents: map[Liz:12000 Amy:15000 Mike:9000]

Pointers in Go

Go supports pointers, allowing you to pass references to values and records within your program.

The syntax for pointer declaration is as follows:

var pointer_name *pointer_data_type

Eg: var b *int

func main() {

b := 255

a := &b

fmt.Println(“address of b is”, a)

fmt.Println(“value of b is”, *a)

*a++

fmt.Println(“new value of b is”, b)

}

It prints the following output:

  • The address of b is 0x10414020.
  • The value of b is 255.
  • The new value of b is 256.

Structure in Go

To define a structure, you must use the type and struct statements. The struct statement defines a new data type, with multiple members for your program. The type statement binds a name with the type which is ‘struct’ in our case. The format of the struct statement is as follows:

type struct_variable_type struct {

member definition;

member definition;

...

member definition;

}

Once a structure type is defined, it can be used to declare variables of that type using the following syntax:

variable_name := structure_variable_type {value1, value2...valuen}

type Books struct {

title string

author string

subject string

book_id int

}

func main() {

var Book1 Books /* Declare Book1 of type Book */

var Book2 Books /* Declare Book2 of type Book */

/* book 1 specification */

Book1.title = “Wings of Fire”

Book1.author = “ A.P. J. Abdul Kalam”

Book1.subject = “An Autobiography”

Book1.book_id = 63108786

/* book 2 specification */

Book2.title = “Academic English”

Book2.author = “Pearson”

Book2.subject = “Check your English Proficiency”

Book2.book_id = 6495700

/* print Book1 info */

fmt.Printf( “Book 1 title : %s\n”, Book1.title)

fmt.Printf( “Book 1 author : %s\n”, Book1.author)

fmt.Printf( “Book 1 subject : %s\n”, Book1.subject)

fmt.Printf( “Book 1 book_id : %d\n”, Book1.book_id)

}

o/p

Book 1 title : Wings of Fire

Book 1 author : A.P. J. Abdul Kalam

Book 1 subject : An Autobiography

Book 1 book_id : 63108786

Interfaces

Go programming provides another data type called interfaces, which are a set of method signatures. Interface specifies what methods a type should have, and the type decides how to implement these methods.

import “fmt”

/* define an interface */

type SalaryCalculator interface {

CalculateSalary() int

}

/* define a permanent employee */

type Permanent struct {

empId,basicpay,pf int

}

/* define a contract employee */

type Contract struct {

empId,basicpay int

}

//salary of permanent employee is sum of basic pay and pf

func (p Permanent) CalculateSalary() int {

return p.basicpay + p.pf

}

//salary of contract employee is the basic pay alone

func (c Contract) CalculateSalary() int {

return c.basicpay

}

/* define a method for SalaryCalculator */

func getSal( salarycalculator SalaryCalculator) int {

return salarycalculator.CalculateSalary()

}

func main() {

perm := Permanent{empId:10,basicpay:40000,pf:8000}

cont := Contract {empId:20, basicpay:25000}

fmt.Printf(“Permanent salary: %d\n”,getSal(perm))

fmt.Printf(“Contract salary: %d\n”,getSal(cont))

}

The Output will be:

  • Permanent salary: 48000
  • Contract salary: 25000

To reiterate, Go, which is sufficiently mature and stable has its own elegance and programming idioms that make the language productive and fun to code. Go also provides a comprehensive standard library with the core packages that programmers need to build real world and Web based programs. Though originally designed for systems programming, Go has become increasingly popular with Web application development, and can be found in many open source and commercial software applications. To sum up, Golang, with its concurrency, channels, interfaces, inheritance, unit testing and packages, is easier to learn for freshers, compared to experienced developers, because they can quickly understand and adapt.

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here