Learning Go

Hello, World!

Golang is a modern statistically typed and compiled language from Google.

In each golang program you need to define a package name at the top. So if you need to import your code into some other program you can use this package name to import. Execution of a golang project starts in the package “main”. So let’s define our package as main.

package main

Go follows a similar pattern as C and has a main function where the execution begins. In go functions are defined using func keyword.

This is an example main function:

func main () {

}

Now to print something we need to use the Println function from the package “fmt”

To import a function you just write import following the package name in “”.

import "somemodule"

Here is an example program to print “Hello World!”

package main

import "fmt"

func main () {
    fmt.Println("This line is printed")
}

We dont need to add semi colons after each line in Go. The compiler takes care of it.

The fmt package also has a Printf() function similar to printf in C. It can be used in the same way as it is used in C.

fmt.Printf("%d is a number",10)

Variables

A variable is a name given to a storage area that the programs can manipulate. The name of a variable can be composed of letters, digits, and the underscore character. It must begin with either a letter or an underscore.

The general code to declare a variable in golang is

var <name of variable> <type of variable>

Numbers

Variables are arithmetic types and represent the following values throughout the program. (a) integer types (b) floating point

To define an integer, use the following syntax:

var a int = 4
var b, c int
b = 5
c = 10
fmt.Println(a)
fmt.Println(b + c)

To define a floating point number, use the following syntax:

var d float64 = 9.14
fmt.Println(d)

Strings

Strings in Go are defined with double quotes.

var s string = "This is string s"
fmt.Println(s)

Single quotes are not used to enable the use of apostrophes in strings without having to escape.

var s string = "Don't worry about apostrophes"
fmt.Println(s)

We can also define multiple line strings wrapping the string in `` quotes.

var s string = `This is a string spanning multiple lines
This is the second line
And this is the third`

fmt.Println(s)

Booleans

Golang supports boolean values with the keywords true and false

Boolean variables are declared in go as follows

var b bool = true

Shorthand Declaration

The := notation serves both as a declaration and as initialization. foo := “bar” is equivalent to var foo string = “bar”

a := 9
b := "golang"
c := 4.17
d := false
e := "Hello"
f := `Do you like golang, so far?`
g := 'M'
h := true

fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
fmt.Println(g)
fmt.Println(h)

Arrays

Arrays are essentially storage spaces that can be filled with as much data as one would like. Variables, unlike arrays, can only contain one piece of data. Now there are some caveats. For instance, an array is syntactically created using one data type, just like variables. Yet, an array grants ease of access and far more capabilities when considering large/vast amounts of data compared to a variable(single storage space/value).

A array in golang has fixed size similar to C and C++ that we give while we define it. We can’t change the size of the array dynamically while the program is running.

Examples

Arrays in golang are defined using the syntax,

var <name of array> [<size of array>]<type of data stored in the array>

Arrays in golang are 0 indexed i.e. the index starts from 0. Let’s make some arrays using the syntax given above

// An array named favNums filled with 3 integers
var favNums [3]int

// Insert data into the array
// The first storage space will be assigned the value of 1. It has an index of 0.
favNums[0] = 1
// The second storage space will be assigned the value of 2. It has an index of 1.
favNums[1] = 2
// The third and final storage space will be assigned the value of 3. It has an index of 2.
favNums[2] = 3

An alternative syntax to the creation of arrays in golang is:

favNums := [4] int {50, 25, 30, 33}

In order to access members of an array, reference the storage space’s address or number you used to create it.

fmt.Println(favNums[0])

output:

50

Slices We already studied about the arrays in golang. But there is one drawback when using golang, they are of fixed size. If we want to increase the size, we need to create another array with higher capacity and copy over the values from the old array. Slices solve this problem.

Slices

Slices are like arrays but they are dynamically resizable i.e. their size is not fixed similar to list in python. Slices are a layer of abstraction over arrays. So when on resizing, the underlying array is changed to a larger array and the contents are copied, but it is completely abstracted from the programmer.

The syntax for defining a slice is

var <slice name> []<datatype of data stored in the slice>

This is an example of defining a slice.

var exampleSlice []int

To add elements to a slice we use the append() function, as shown below

exampleSlice = append(exampleSlice, 1)
exampleSlice = append(exampleSlice, 2)
exampleSlice = append(exampleSlice, 3)

We can do this in a single line like this

exampleSlice := []int{1,2,3}

Remember we studied about the := operator in go in the previous chapters. It enables us to skip adding the var keyword and the type.

To find the current length of the slice we use the len() function, and to find the capacity of the underlying array, we use the cap() function

fmt.Printf("%d is the length of the Slice", len(exampleSlice))              // prints 3
fmt.Printf("%d is the capacity of the underlying array", cap(exampleSlice))

Now let’s print the elements of the slice

fmt.Println(exampleSlice)                   // prints [1 2 3]

You can also create a slice using the make function where you can also give an initial capacity to the slice.

// here 0 is the initial length, and 5 is the initial capacity
// i.e. we haven't added any values but the underlying array has a
// initial capacity of 5 which is later changed dynamically to meet the requirement
exampleSlice := make([]int, 0, 5)

// You can skip the capacity and length and only give the type to get an empty slice
exampleSlice = make([]int)

If-Else

In Golang we have if-else statements to check a condition and execute the relevant code.

if statement

The if statement is used to check if a condition is met and execute the code inside the if block only if the condition is met.

The general syntax is

if <condition> {
    // Code to be executed if the condition is met.
}

Let us write a example code to test if we need to take an umbrella based on if it’s raining or not outside.

isRaining := true

if isRaining {
    fmt.Println("It's raining, take an umbrella")
}

else statement

If the condition in a if statement is not met then we execute the else block if it is defined.

The syntax is

if <condition> {
    // code executes if condition is true
} else {
    // code executes if condition is false
}

One thing to remember here is the else statement should always be in the same line as the closing } of the if statement.

// below code doesn't work as else is not in the same line as if's closing }
if <condition> {
    // code executes if condition is true
}
else {
    // code executes if condition is false
}

In the last module, we checked if it’s raining and we gave a message if it is raining. But our code doesn’t print anything if it is not raining. Let us fix it by adding an else statement and providing more information.

isRaining := true

if isRaining {
    fmt.Println("It's raining, take an umbrella")
} else {
    fmt.Println("It's not raining. Umbrella not needed")
}

Example

Let’s write an example code to check if the user’s name is John or not

userName := "John"

// prints You are John
if userName == "John" {
    fmt.Println("You are John")
} else {
    fmt.Println("You are not John")
}

// let's try again changing the username variable
userName := "Mathew"

// prints You are not John
if userName == "John" {
    fmt.Println("You are John")
} else {
    fmt.Println("You are not John")
}

You can cascade if statement in an else statement to check for more conditions and run the relevant code.

Now let’s write some code to check if a user age is below 20 or between 20 and 60 or above 60.

userAge := 26

if userAge < 20 {
    fmt.Println("Below 20")
} else if userAge >= 20 && userAge <= 60 {
    fmt.Println("Between 20 and 60")
} else {
    fmt.Println("Above 60")
}

The if statement also provides an option to initialize a variable and test the condition within the if statement. The general syntax in this case is

if <init>;<condition> {
    // code to execute if condition is true
}

An example code is given below.

if userName := "Jeremy"; userName == "John" {
    fmt.Println("You are John")
} else {
    fmt.Println("You are not John")
}

Loops

Go has only one looping construct, the for loop.

The basic for loop has three components separated by semicolons:

  • the init statement: executed before the first iteration
  • the condition expression: evaluated before every iteration
  • the post statement: executed at the end of every iteration

The init statement will often be a short variable declaration, and the variables declared there are visible only in the scope of the for statement.

The loop will stop iterating once the boolean condition evaluates to false.

Note: Unlike other languages like C, Java, or JavaScript there are no parentheses surrounding the three components of the for statement and the braces { } are always required

Examples

The following code prints numbers from 1 to 9.

package main

import "fmt"

func main() {
    for i := 0; i < 10; i++ {
        fmt.Println(i)
    }
}

You can omit the init and post statement in the for loop to get a while loop. The below loop works like a while loop

package main

import "fmt"

func main() {
    i := 0

    for i < 10 {
        fmt.Println(i)
        i++
    }
}

Golang also provides a for-range loop to loop over an array, slice or few other datastructures.

The for-range loop provides us access to the index and value of the elements in the array or slice we are looping through as shown below

package main

import "fmt"

func main() {
    myList := []int{1,2,3}

    for index, value := range myList {
        fmt.Printf("%d is index, %d is value", index, value)
    }
}

We can ignore one or both the fields in a for-range loop by giving an _ instead of giving a variable name

    for _, value := range myList {
        fmt.Println(value)
    }

Functions

Functions provide a way to divide your code into logical blocks and reuse them minimising the time and effort and improve the managability of the code.

Functions in Go

Functions in golang are defined using the func keyword.

The syntax to define a function in go

func <name of the function> (<inputs to the function>) (<datatypes of return values from the function>) {
    // your code here
}

Let’s write a add function using this syntax

func add (a int, b int) int {
    return a + b
}

How to call a function in your code

Calling a function is as easy as writing the function name and giving it the arguments. Now for an example let’s call our add function in the main method.

package main

import "fmt"

func main() {
    sum := add(3, 5)

    fmt.Println(sum)        // prints 8
}

Go also let’s you ignore specific fields in the return values using the _ variable.

package main

import "fmt"

func sumAndDiff (a int, b int) (int, int) {
    return a + b, a - b
}

func main() {
    sum, _ := sumAndDiff(5, 3)      // the 2nd variable is ignored and not used

    fmt.Println(sum)                // prints 8
}

We can also add named return values so that we dont need to deliberately return something in the function. But beware, use this only in small functions.

package main

import "fmt"

func add (a int, b int) (sum int) {         // here we are defining the variable name of what we are returning
    sum = a + b                             // so no need for a return statement, go takes care of it
}

func main() {
    sum := add(3, 5)

    fmt.Println(sum)                // prints 8
}

The fmt module

The builtin fmt package provides many useful functions which are used to print to console or format to a string. Let’s take a look at few of the most used functions.

fmt.Println()

fmt.Println() is the basic print function golang has to offer. It prints the values given to it seperated by commas and adds a newline at the end.

// fmt.Println() usage
fmt.Println("Hello")                            // prints "Hello"

// multiple arguments of different types can be given seperated by commas
fmt.Println("Hello", 22, 98.3, true)            // prints "Hello 22 98.3 true"

// you can also pass variables as arguments
a := "Hello"
b := "World"

fmt.Println(a, b)                               // prints "Hello World"

fmt.Printf()

fmt.Printf() is similar to printf() in C language. We give a string with keywords like %d, %v and give the other arguments which get formatted to these keywords.

// fmt.Printf() usage
fmt.Printf("%s is %d years old.", "Jon Snow", 30)   // prints "Jon Snow is 30 years old."

// using %v for printing everything
fmt.Printf("%v is %v years old.", "Jon Snow", 30)   // prints "Jon Snow is 30 years old."

// let's try printing type of any variable
name := "Jon Snow"
fmt.Printf("%T is the type of %v", name, name)      // prints "string is the type of Jon Snow"
Common keywords that are used and what variables are formatted by them

%d - integers
%s - strings
%f - floating point number
%t - boolean
%T - prints the type of the variable given
%v - prints any object of any type

fmt.Sprintf()

fmt.Sprintf() works just like fmt.Printf() but instead of printing to the console it returns the formatted string. It’s highly useful for creating formatted strings from variables in golang.

Let’s see the function in action.

// the function returns a formatted string.
s := fmt.Sprintf("%s is the son of %s", "Harry", "Lily")  // returns a string "Harry is the son of Lily"

// let's print the string s
fmt.Println(s)                                            // prints "Harry is the son of Lily"

The same keywords that we used for formatting in fmt.Printf() apply here too.

Source

https://www.learn-golang.org/

Previous