Learn Golang

Why Go  : Easy to use and fast compile time

Features:

-Simple

-Fast compile times

-Auto and fast Garbage collected

-Better in concurrency

 

Go to https://tour.golang.org  and check out all the details. Download Go from here : https://golang.org/dl/  It has nice play area for learning and practicing. Also Try Gopher Slack for GO community

 

Setting up the environment:

Try to put the absolute path if you are using editors

The installation directory is generally c:/go and it gets distributed in this path also

c:/users/username/go.

Try

GOPATH = Path to your local project

PATH = otherpaths; c:/users/username/go

 

Now check the installation by going to command prompt and type : “go version”.

 

Let’s start with sample code:

package main
import “fmt”
func main() {
    fmt.Println(“HI”)
}

 

Here the package name should be declared and main is by default the starting package name, and similarly func main is the entry point of the program

 

 

Running and creating executables

I have project name demo1 in folder c:/work/go

To run the file directly, which prints HI

C:\work\go\demo1>go run src/Main.go

Hi

 

To create executable in bin folder

C:\work\go\demo1>go build test

C:\work\go\demo1>go install test

C:\work\go\demo1\bin>test.exe

HI

 

Variables

 

package main
import “fmt”
func main() {
    var one int = 1
    var two int
    two = 2
    three := 3
    fmt.Printf(“variable name %v  and type  %T \n”, one, one)
    fmt.Printf(“variable name %v  and type  %T \n”, two, two)
    fmt.Printf(“variable name %v  and type  %T \n”, three, three)
}
 

C:\work\go\demo1>go run src/test/Main.go

variable name 1  and type  int

variable name 2  and type  int

variable name 3  and type  int

 

The variable name can be lazy initialized like variable two in above code or directly assigned  like variable one above. We can also use := syntax which allows GO compiler to auto detect the type

We can also create variable blocks where we remove the extra var clutter

var(
    abc string “one”
    def string “two”
    i int 2
)

 

 

Shadowing: The variable declared in the functions/local overrides the value defined in package level

Local variable which are declared and not used will throw compile time errors

 

Variables naming conventions and scopes:

Lowercase first letter > scope within package >  var e int =0

Uppercase first letter > scope is global and outside package >  var E int =0

Within block > scope is within block of code > func abc{ var E int =0}

 

 

Working with Strings

Use “strconv” library for converting ints to strings, and if we directly typecast, then we will get asci value of that.We can use strconv.Itoa(i)

Imaginary variables in complex variables: we can declare complex variables having imaginary i value

func main() {
    k := 1 + 3i
    var b complex64 = 2 + 2i
    var c complex64 = complex(3, 4)
    fmt.Println(k)
    fmt.Println(b)
    fmt.Println(c)
}

C:\work\go\demo1>go run src/test/Main.go

(1+3i)

(2+2i)

(3+4i)

 

 

Iota: we can use iota as counters. It starts with value 0 and then increments whenever used in that block

const (
    a = iota
    b = iota
    c = iota
    d = iota
)
func main() {
    fmt.Print(“a , b, c, d “, a, b, c, d)
}

C:\work\go\demo1>go run src/test/Main.go

a , b, c, d 0 1 2 3

 

 

Arrays and Slices

Initializing arrays: Ist value is the length of array and then type and if we don’t specify the size, a slice is created

    arr := [4]string{“a”, “b”, “c”, “d”}
    bb := []int{2, 3}

 

In arrays, if we copy and change data, the data gets changed in later one only. However, in slice, they both will point to same reference and this on change, both variables gets updated.Arrays have fixed length, whereas slices has variable length. Slices almost doubles up their size when we add new element.

 

Using make function to create arrays

    a := […]int{1, 2, 3, 4}
    b := make([]int, 3)     // make array of size 3
    c := make([]int, 4, 10) // make array of size 3 and capacity 10
    fmt.Println(len(a))
    fmt.Println(len(b))
    fmt.Println(len(c))

C:\work\go\demo1>go run src/test/Main.go

4

3

4

 

Use of append for slices

    a := []int{1, 2, 3, 4}
    a = append(a, 5, 1)
    fmt.Println(a)

C:\work\go\demo1>go run src/test/Main.go

[1 2 3 4 5 1]

 

 

Pointers: Pointers are defined by ‘&’ which specifies that the value will point to the reference of the assigned variable.

 

 

Maps and Structs

 

Ways of making maps

func main() {
    m := map[string]int{
        “aa”: 12,
        “bb”: 13,
    }
    m2 := make(map[string]int, 5)
    fmt.Println(m)
    fmt.Println(m2)
}

C:\work\go\demo1>go run src/test/Main.go

map[aa:12 bb:13]

map[]

 

Some functions of map

    m := map[string]int{
        “aa”: 12,
        “bb”: 13,
    }
    fmt.Println(m[“aa”])    //prints the value from key
    value1, ok := m[“aa”]   //, ok check if value exists
    fmt.Println(value1, ok) //print value and ok
    value1, ok = m[“aa11”]  //, ok check if value exists (not existing key)
    fmt.Println(value1, ok) //print value and ok
    fmt.Println(len(m))     //length of map
    fmt.Println(m)

C:\work\go\demo1>go run src/test/Main.go

12

12 true

0 false

2

map[aa:12 bb:13]

 

Maps are collections having key/value pair and can be created using make or literals.

We can use “check, ok” for checking if there is key in the map. If there is no value, check will have “0” default value and “ok” will be false.

 

 

Struct : can hold data of any types. We can consider that as Java classes having different attributes.

 

type Person struct {
    id         int
    name       string
    department string
    roles      []string
}
func main() {
    p := Person{
        id:         1,
        name:       “fname”,
        department: “finance”,
        roles:      []string{“HR”, “Maintenance”},
    }
    fmt.Println(p) //prints the value struct person
}

C:\work\go\demo1>go run src/test/Main.go

{1 fname finance [HR Maintenance]}

Data References: Unlike slices and maps, structs refer to independent references.  If we assign struct value to other variable and then change the value in that variable, the current one will still have its old value.

 

 

There is no inheritance in golang, but we have composition.

 

Structs also allow tags which are a nice feature, wherein we can specify some properties, like field validations also. It needs “reflect” package

import (
    “fmt”
    “reflect”
)
type Person struct {
    id   int
    name string `required`
}
func main() {
    p := reflect.TypeOf(Person{})
    field, _ := p.FieldByName(“name”)
    fmt.Print(field.Tag)
}

C:\work\go\demo1>go run src/test/Main.go

required

 

If Statements:

func main() {
    var i int = 32
    if i == 1 {
        fmt.Print(“1st condition true”)
    } else if i == 2 {
        fmt.Print(“1st else if condition true”)
    } else {
        fmt.Print(“default condition”)
    }

The rules are the same as like other languages.

 

Switch

func main() {
    switch “test” {
    case “a”:
        {
            fmt.Print(“case1”)
        }
    case “test”:
        {
            fmt.Print(“case2”)
        }
    default:
        {
            fmt.Print(“case3”)
        }
    }
}

C:\work\go\demo1>go run src/test/Main.go

case2

Same applies for switch also where all rules are almost similar to other languages.

For loops

for i := 0; i < 3; i++ {
        fmt.Print(i)
    }

We can use the above format to create a for a loop.

 

 

Defer and panic

Defer statement which is generally used to close the resources are called after the function completes

Defer uses Lifo if there are multiple defers in a function.

Panic is like exceptions.

Panic always happens after defer.

Recover : Recover can be used to come out from panic mode.

 

 

Goroutines

These are like threads in GoLang

Add “go” in front of statement and it will be executed as a separate thread

We can also use the wait group to tell the compiler about the threads status.

 

var waitGroup = sync.WaitGroup{} //creates a wait group
func main() {
    fmt.Println(“start”)
    waitGroup.Add(1) //tells the waitgroup to add thread
    go hello()       // calls the thread/goroutine
    waitGroup.Wait() //wait till the thread is compelted
    fmt.Println(“end”)
}
func hello() {
    fmt.Println(“hello”)
    waitGroup.Done() // tells the waitgroup that it is done.
}

 

 

 

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *