Technology / Tutorials /

Go Programming For Beginners

18 Sep 2014 4:45pm, by

Editor’s Note: Programming language popularity can be defined according to all sorts of criteria, as a post on The New Relic site recently explored. For example, the post cites Go as trending as a programming language for web development.

For us, Go, also called golang, is one of the more interesting programming languages due to its use in applications that represent a new generation of loosely coupled apps and infrastructure. DockerCloud Foundry, CoreOS, Digital Ocean… all of these companies have made commitments to Go.

The New Stack, for us in many ways, represents a way to explore new thinking about technology. The diversity and rate of innovation means that it’s new for all of us at some point. With this in mind, we are introducing a new series of introductions to new stack technologies. For starters, we asked Kartik Nayak, an engineering student in Bangalore, to write his version of what a beginner’s guide to Go might look like. So, here you go, The New Stack Intros: Beginner’s Guide to Go. Cheers. Alex.

go muscat

Go, initially developed at Google, is a statically-typed language with syntax loosely derived from that of C, adding garbage collection, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library.

Created By:

Go was initially developed in 2007 at Google and was released in November 2009. The current stable release is V1.3.

Usage of GO over Time:

go progress

Source : http://talks.golang.org/2014/hellogophers.slide

Why Go?

 Go is like a better C, from the guys that didn’t bring you C++” — Ikai Lan

 Features of Go:

  • Syntax and environment adopting patterns.
  • Fast compilation time.
  • Remote package management.
  • Online package documentation.
  • Built-in concurrency primitives.
  • Interfaces to replace virtual inheritance.
  • Type embedding to replace non-virtual inheritance.
  • Compiled into statically linked native binaries without external dependencies.
  • Simple language specifications.
  • Large built-in library.
  • Light testing framework.

The Go Language

Types

Integers

Integers are numbers without a decimal component. Unlike us, the computers use a base-2 representation called binary system. Go’s integer types are : uint8, int8, uint16, int16, uint32, int32, uint64, int64.

8, 16, 32 and 64 tell us how many bits each of the types use.

Also, a byte is an alias for uint8 and a rune for int32.

There are also 3 machine dependent integer types: uint, int and uintptr. They are machine dependent because their size depends on the type of architecture you are using.

var x int = 404
var y uint32 = 234242

Floating Point Numbers

Floating Point Numbers can be defined as numbers with a decimal component or more generally known as Real Numbers.

Go has two floating point types : float32 and float64

Go also has two complex number types : complex64 and complex128

var x float64 = 34.23
var y complex64 = 3 + 2i

Strings

A string is a sequence of characters of a definite length for textual representation.

String literals in Go can be created using either double quotes “Hello World” or back quotes `Hello World`.

Double quotes cannot contain newlines but allow special escape sequences like \n and \t.

Strings can be concatenated using the + symbol.

The length of a string can be obtained using the len(<string>) function.

Using indices, individual character of a string can be obtained.

var weird string = "weird string"
a := `Hello to all`

Boolean

Booleans are a special 1 bit integer type used to indicate True or False.

The logical operators which can be used on booleans are :

and &&
or ||
not !

Variables

Variables in Go are initialized using the var keyword and then followed by the variable name and variable type.

var x int
var y string = "Hello world"

You can also initialize variables in a shorter way.

Here the data type is internally assigned.

x := 8
y := "Hello world"

You can also declare constants using the assignment operator, Numeric constants in Go are high-precision values.

const y = "Hello world"
const Pi = 3.14

Loops and Control Structures

For

For loops are used just as in C and Java.

for i := 0; i < 10; i++ {
	fmt.Println("The value of i : ", i)
}

or

for i != 0 {
	fmt.Println("The value of i :", i)
}

The range keyword can be used to range over a list of values also

a := [ ]int{4, 3, 1, 7, 3, 9, 2}
for _, i := range a {
	sum = sum + i
}

If

If statements are also similar to those in C and Java.

if num % 2 == 0 {
	fmt.Println("Even")
} else {
	fmt.Println("Odd")
}

Switch

Switch statements starts with the keyword switch and follows with multiple cases.

switch i {
	case 0 : fmt.Println("Zero")
	case 1 : fmt.Println("One")
	case 2 : fmt.Println("Two")
	case 3 : fmt.Println("Three")
	case 4 : fmt.Println("Four")
	case 5 : fmt.Println("Five")
	case 6 : fmt.Println("Six")
	case 7 : fmt.Println("Seven")
	case 8 : fmt.Println("Eight")
	case 9 : fmt.Println("Nine")
	default : fmt.Println("Unknown Number")
}

Arrays, Slices and Maps

Arrays

The type [n]T is an array of size n of type T.

var a [10]int 
x := [5]float64 {
	34,
	63,
	56,
	84,
	23,
}

Slices

A slice is a segment of an array. The length of a slice is not fixed. Creation of slice is via the make command.

x := make([]int, 5)

Maps

A map is an unordered collection of key-value pairs. Also known as an associative array, a hash table or a dictionary, maps are used to look up a value by its associated key.

var x map[string]int
x["Hello"] = 1

Functions

Functions are defined using the keyword func followed by the function name and arguments and the return values.

func say_hello() {
	fmt.Println("Hello From the function")
}

If the result parameters are named, a return statement without arguments return the current values of the variables

func details(a []int) (x, y int) {
	x := len(a)
	y := cap(a)
}

Multiple return types

Go supports multiple return types.

func calculate(a, b int) (sum, prod int) {
	sum := a + b
	prod := a * b
	return sum, prod
}

func main() {
	a, b := calculate(3, 4)
}

Variadic Function

Functions can take 0 to undefined variables of a particular data type.

func total(args ...int) (sum int) {
	sum := 0
	for _, i := range args {
		sum = sum + i
	}
	return sum
}

Closure

Consider the following example

func main() {
dog := func() {
		fmt.Println("Woof!")
}
	dog()
}

Here we are actually assigning the function to a variable.

Similarly.

func increm() func() int {
	x := 0
	return func() int {
		x = x + 1
		return x
	}
}

func main() {
	y := increm()
	fmt.Println(y)
	fmt.Println(y)
}

Output :
1
2

Here, the func increm returns a func of type func() int which still refers to the variable x which is outside the body of the func. This is known as a closure func.

Pointers

Pointers, yes pointers! Go has pointers, but no pointer arithmetic.

x := 5
y := &x
fmt.Println(*y)

Output :
5

y points to x and the value of y is obtained using a * operator. The & operator is used to get the address of a variable.

The new operator is used to allocate memory to a pointer variable.

x := new(int)
*x = 9
fmt.Println(*x)

Output :
9

Structures, Methods and Interfaces

Structures
A structure is a user defined data type which contains named fields. A structure is basically an object in Go which has data types and methods on it.

type dog struct {
	breed string
	age int
	owner string
}

type cow struct {
	age int
	farm string
}

rocky := dog { "Lab", 5, "Roy" }
bigcow := cow { age : 3, farm : "Donalds" }
fmt.Println("Dogs age is : ", rocky.age )
fmt.Println("Cows age is : ", bigcow.age )

We declare structures using the type and struct keyword. Individual elements of the structure are accessed using the dot operator.

Methods

Assume, we want to know what the dog/cow says, we can define a method on the given structure to perform a specific task, in our case to speak.

func (d dog) speak() string {
	return "Woof"
}

func (c cow) speak() string {
	return "Moo"
}

With this you can now use:

fmt.Println(dog.speak())
fmt.Println(cow.speak())

Output :
Woof
Moo

Here, the function speak takes a dog and cow types respectively and responds with a string based on the type.

Interfaces

Interfaces are basically a collection of methods. Lets define an interface on the function speak.

type Speaker interface {
	speak() string
}

So, any type which has a method called speak automatically satisfies the Speaker interface.

Hence we can have.

var a Speaker
a :=  dog { "Lab", 5, "Roy" }
fmt.Println(a)
a := cow { age : 3, farm : "Donalds" }
fmt.Println(a)

Output :
{Lab 5 Roy}
{3 Donalds}

In Go interfaces are implicitly satisfied, this one of the best features of the language.

Let us take an example, the Println function takes an interface which holds a method of type String() string

Defining our own method for the dog type we can print the data as per what is most suitable to us.

func (d dog) String() string {
	return fmt.Sprintf("The dog is %s, it is currently %d years old and belongs to %s", d.breed, d.age, d.owner)
}
b :=dog { "Lab", 5, "Roy" }
fmt.Println(b)

Output :
The dog is Lab, It is 5 years old and belongs to Roy

Because the dog has a String function and the interface taken by Println requires a String function, we satisfy that interface.

Concurrency

Go has a rich support for concurrency via goroutines and channels. This is one of the highlights of the language.

Goroutines

Goroutines can be described as functions which run concurrently from other functions. They’re invoked following the go keyword. As the function is invoked it runs concurrently and the rest of the code is executed without waiting for the completion of that function. The main function is implicitly a goroutine.

func foo(n int) {
	for i := 0; i < n; i = i + 2; {
		fmt.Printf("%d : %d ", n, i)
		time.Sleep(time.Milliseconds * 50)
        }
} 

func main() {
      for i := 0; i < 10; i++ {
            go f(i)
    }
     var input string
     fmt.Scanln(&input)
}

Now the function prints out all the no’s from different goroutines, as they’re concurrently run. The sleeper makes sure that a particular routine waits for 50ms before the next iteration, this gives time for the other routines to run.

Channels

For intercommunication of concurrent functions we use channels. Channels must be created before being used, using the chan keyword. Let us create a channel of type string.

var c chan string = make(chan string)

Lets consider a small example

func sender(c chan string) {
     for {
              c <- "Hello"
     }
}
func receiver(c chan string) {
     for{
                fmt.Println(

Here the sender  function continuously sends the string to the c channel and the receiver function prints the value received from the channel continuously.

The function prototype can also restrict the direction of data flow from and to the channel.

Let us replace the sender and the receiver function

func sender(c chan<- string)
func receiver(c <-chan string)

There is also a select option when handling channels, this acts like a switch statement selecting the channel which is ready.

Final words

To move ahead with Go, have a look at the official documentation and I recommend the tour.

Also go through the talks held on Go, in various Gophercons I will be attending Gopeherconf India next year.

Have a look at the way Go code is organised and also how the testing framework is used in Go. Learn to use the automatic code formatting tool gofmt and also the automatic documentation generator godoc.

References

 

Kartik Nayak is an engineering student based in Bangalore, India. When not attending college, he can be seen learning about the linux kernel and coding. Also indulges in casual photography.

Feature image by Chris Nokleberg via the Go web site.

 


A digest of the week’s most important stories & analyses.

View / Add Comments