The Ops Community

Cover image for GOLANG for Beginners
Harkirat Singh
Harkirat Singh

Posted on • Updated on

GOLANG for Beginners

Table of Content

What is Go ?

Go is an open-sourced programming language that was first published in 2009 and developed by Google’s Rob Pike, Robert Griesemer, and Ken Thompson. Based on the syntax of C, it comes with some changes and improvements to safely manage memory usage, manage objects, and provide static or strict typing along with concurrency.

Go was created with the goal of:

  • The simplicity of use while increasing productivity
  • Providing a high level of code efficiency
  • Advanced performance for businesses.

Tutorials

Hello World

Our first program will print the classic “hello world” message. Here’s the source code.

 package main

import "fmt"

func main() {
    fmt.Println("hello world")
}
Enter fullscreen mode Exit fullscreen mode

To run a go program , create a file named hello-world.go and use go run .

Helloworld

To build our programs into binaries just use go build .

build

Variables

var declares a variable value

You can Declare multiple variables at once . Variable value can be changed , := syntax is shorthand for declaring and initializing a variable like var name string ="golang"
Note- you have to use every variable you declared , that's the beauty of golang

package main

import "fmt"

func main() {

    var name="golang"
    fmt.Println(name)
    var fruit string="Apple"
    fmt.Println(fruit)
    var age=10
    fmt.Println(age)
    var day int=2
    fmt.Println(day)
    week:=4
    fmt.Println(week)
    var flag bool =true
    fmt.Println(flag)
}
Enter fullscreen mode Exit fullscreen mode

Output -

variable

Constants

const declare a constant value
You cannot change value of const variable , you have to declare and initialization at the same time .

package main

import "fmt"

func main() {
    const pi=3.14
    fmt.Println(pi)
}
Enter fullscreen mode Exit fullscreen mode

Output -
const

For

In golang we only have for loop , which is enough . A for loop without any condition is just like while(true) , you can use break or return to get out of this loop.

package main

import "fmt"

func main() {

    i := 1
    for i <= 3 {
        fmt.Println(i)
        i = i + 1
    }

    for j := 7; j <= 9; j++ {
        if j==8 {
            continue
        }
        fmt.Println(j)
    }

    for {                     // Infinite Loop
        fmt.Println("loop")
        break
    }


}
Enter fullscreen mode Exit fullscreen mode

If/Else

You can use if with out else .
To branch multiple condition you can use if ... else if ... else.
Here’s a basic example.

package main

import "fmt"

func main() {
    i :=10
    if i<10 {
        fmt.Println("Number entered is one digit only")
    }else if i>10 &&i<99{
        fmt.Println("Number entered is two digit only")
    }else{
        fmt.Println("Number entered is more than two digit only")
    }

}
Enter fullscreen mode Exit fullscreen mode

Output -
cond

Switch

Switch statements express conditionals across many branches.
You can use commas to separate multiple expressions in the same case statement. We use the optional default case in this example as well.
Here’s a basic switch.

package main

import "fmt"

func main(){
    cityName := "Newyork"
    switch cityName {
    case "Newyork" :
        fmt.Println("It is beautiful")
    case "Berlin","London": // mulitple condition 
        fmt.Println("It is great people living") 
    default:
        fmt.Println("no city")
    }
}
Enter fullscreen mode Exit fullscreen mode

Switch

Arrays

In Go, an array is a numbered sequence of elements of a fixed length.
The builtin len returns the length of an array.
Array types are one-dimensional, but you can compose types to build multi-dimensional data structures.

package main

import "fmt"

func main(){
    var bookings = [3]string{} // 
    // var bookings [50]string // alternative way 
    bookings[0]="John"
    var len=len(bookings) // length of array
    fmt.Printf("Array %v of length %v",bookings ,len) // print whole array

    var twoD [2][3]int
    for i := 0; i < 2; i++ {
        for j := 0; j < 3; j++ {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2D : ",twoD)
}
Enter fullscreen mode Exit fullscreen mode

Output -

Arrays

Maps

Maps are Go’s built-in associative data type (sometimes called hashes or dicts in other languages).
The builtin len returns the number of key/value pairs when called on a map.
To create an empty map, use the builtin make: make(map[key-type]val-type).
Set key/value pairs using typical name[key] = val syntax.
The builtin delete removes key/value pairs from a map.

package main

import (
    "fmt"
)

// 1. Unique keys to values
// 2. You can retrieve the value with the key
func main(){
    var userData=make(map[string]string)  // [type]type
    userData["FirstName"]="John"
    userData["LastName"]="Cena"
    userData["email"]="john@cena.com"
    fmt.Printf("Map %v of length %v \n",userData,len(userData))

}
Enter fullscreen mode Exit fullscreen mode

Output -
Maps

Slices

Slices are a key data type in Go, giving a more powerful interface to sequences than arrays. In slices we don't have to specify the length i.e. Dynamic in length .
Here is a basics example

package main

import (
    "fmt"
)


func main(){
    var names []string  // s:=make([]string,3) with a specified length
    names =append(names,"john")
    names=append(names,"ben")
    names=append(names, "harry")
    l:=names[1:]
    fmt.Println("Slice ",names)
    fmt.Printf("SubList of name is %v",l)

} 
Enter fullscreen mode Exit fullscreen mode

Output -
slice

Functions

Functions are central in Go, you can return single as well as multiple values in Golang .
Here's is a basic examples of functions

package main
import "fmt"

func equal(a int,b int) bool{ //Return a single value
    return a==b

}
func bodmas(a int , b int) (int,int,int) { // Return multiple values
    sums:=a+b
    min:=a-b
    mul:=a*b
    return sums ,min ,mul
}
func main(){
    isequal:=equal(10,10)
    fmt.Println(isequal)
    a,b,c:=bodmas(20,10)
    fmt.Println(a,b,c);
}
Enter fullscreen mode Exit fullscreen mode

Output -
Functions

Pointers

Golang supports pointers , allowing you to pass references to values . Here &val is memory address of that variable .
Pointers can be printed too.

package main
import "fmt"
func change(val int){
    val=0
}
func changePtr(val *int){
    *val=0
}
func main(){
    val:=1
    fmt.Printf("initial %v\n",val)
    change(val)
    fmt.Printf("after function change %v \n",val)
    changePtr(&val)
    fmt.Printf("after function changePtr %v",val)
}
Enter fullscreen mode Exit fullscreen mode

Output -
pointers

Structs

A struct in Golang is a user-defined type that allows to group/combine items of possibly different types into a single type.
Here UserData struct type has firstName, lastName, age, dob fields of different datatype .

type UserData struct{
    firstName string
    lastName string
    age uint
    dob string
}
Enter fullscreen mode Exit fullscreen mode

The above syntax creates a new struct . This concept is similar to classes in object-oriented-programming .

user1:=UserData{firstName:"John",lastName:"Cena",age:45 ,dob: "MM/DD/YYYY" }
name:=user1.firstName // to access the fields 
Enter fullscreen mode Exit fullscreen mode

Here is a basic implementation -

package main

import "fmt"
// Mixed data type
type UserData struct{
    firstName string
    lastName string
    age uint
    dob string
}
var bookings=make([]UserData,0) // array of Userdata type 
func main(){
    bookings = append(bookings, UserData{firstName:"John",lastName:"Cena",age:45 ,dob: "MM/DD/YYYY" })
    fmt.Println(bookings)
    fmt.Printf(" Name : %v %v \n Age : %v \n DOB : %v ",bookings[0].firstName,bookings[0].lastName,bookings[0].age,bookings[0].dob)
}
Enter fullscreen mode Exit fullscreen mode

Output -
structs

Goroutines & WaitGroups

A goroutine is a lightweight thread of execution.

GO keyword
1) Create a separate thread , just like async i.e. code written still works while that thread is executing , If we don't use go keyword then the code will execute that function & then move on to rest statement .
2) go start a new goroutine
A goroutine is a lightweight thread managed
by go runtime
3) Faster and Stay Responsive

Wait Group
1) Wait for the launched goroutine to finish
2) Package "sync" provides basic synchronization functionality
3) Add() - Sets the number go routines to wait for
4) Wait() - Blocks until the wait group counter is 0
5) Done() - Decrement the wait group counter by 1 , So this is called by the goroutine to indicate that it's finished .

package main

import (
    "fmt"
    "time"
    "sync"
)
var wg=sync.WaitGroup{};
func sleep(){
    time.Sleep(2*time.Second)
    fmt.Println("Done ..")
    wg.Done()
}
func main(){
    wg.Add(1)
    fmt.Println("Going......")
    go sleep()
    wg.Wait()

}
Enter fullscreen mode Exit fullscreen mode

Output -
Goroutines

CRUD API

Now we have learnt basic concepts of golang and now we can implement our learning by creating a CRUD api and test the api in Postman .

1) Create a struct Student and Principle .

type Student struct{
    Rollno string `json:"rollno"`
    Name string `json:"name"`
    Class string `json:"class"`
    Principle *Principle `json:"principle"`
}
type Principle struct{
    Name string `json:"name"`
}
Enter fullscreen mode Exit fullscreen mode

2) Handle the Get Request

func getstudents(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(students)

}
Enter fullscreen mode Exit fullscreen mode

3) Handle the delete Request

func deleteStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    param := mux.Vars(r)
    for index, item := range students {
        if item.Rollno == param["rollno"] {
            students = append(students[:index], students[index+1:]...)
            break
        }
    }
    json.NewEncoder(w).Encode(students)
}
Enter fullscreen mode Exit fullscreen mode

4) Create a new student

func createStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    var student Student
    _ = json.NewDecoder(r.Body).Decode(&student)
    student.Rollno = strconv.Itoa(rand.Intn(100000))
    students = append(students, student)
    json.NewEncoder(w).Encode(student)
}
Enter fullscreen mode Exit fullscreen mode

5) Update a Particular students -

func updateStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r)
    for index, item := range students {
        if item.Rollno == params["rollno"] {
            students = append(students[:index], students[index+1:]...)
            var student Student
            _ = json.NewDecoder(r.Body).Decode(&student)
            student.Rollno = params["rollno"]
            students = append(students, student)
            json.NewEncoder(w).Encode(student)
        }
    }

}
Enter fullscreen mode Exit fullscreen mode

6) Get a student details with a rollno

func getStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    param := mux.Vars(r)
    for _, item := range students {
        if item.Rollno == param["rollno"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Here is the full code .

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "math/rand"
    "net/http"
    "strconv"

    "github.com/gorilla/mux"
)

type Student struct {
    Rollno    string     `json:"rollno"`
    Name      string     `json:"name"`
    Class     string     `json:"class"`
    Principle *Principle `json:"principle"`
}
type Principle struct {
    Name string `json:"name"`
}

var students []Student

func getstudents(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(students)

}
func deleteStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    param := mux.Vars(r)
    for index, item := range students {
        if item.Rollno == param["rollno"] {
            students = append(students[:index], students[index+1:]...)
            break
        }
    }
    json.NewEncoder(w).Encode(students)
}
func createStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    var student Student
    _ = json.NewDecoder(r.Body).Decode(&student)
    student.Rollno = strconv.Itoa(rand.Intn(100000))
    students = append(students, student)
    json.NewEncoder(w).Encode(student)
}
func updateStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r)
    for index, item := range students {
        if item.Rollno == params["rollno"] {
            students = append(students[:index], students[index+1:]...)
            var student Student
            _ = json.NewDecoder(r.Body).Decode(&student)
            student.Rollno = params["rollno"]
            students = append(students, student)
            json.NewEncoder(w).Encode(student)
        }
    }

}
func getStudent(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    param := mux.Vars(r)
    for _, item := range students {
        if item.Rollno == param["rollno"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
}
func main() {
    r := mux.NewRouter()
    students = append(students, Student{Rollno: "1", Name: "Harry", Class: "10", Principle: &Principle{Name: "John Clarks"}})
    students = append(students, Student{Rollno: "2", Name: "Mandy", Class: "9", Principle: &Principle{Name: "Shawn Medes"}})
    r.HandleFunc("/", getstudents).Methods("GET")
    r.HandleFunc("/students/{id}", getStudent).Methods("GET")
    r.HandleFunc("/students", createStudent).Methods("POST")
    r.HandleFunc("/students/{id}", updateStudent).Methods("POST")
    r.HandleFunc("/students/{id}", deleteStudent).Methods("DELETE")
    fmt.Printf("Starting server at port 8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}

Enter fullscreen mode Exit fullscreen mode

You can use PostMan to test Api End points .

Resources to learn More about golang -
1) Golang docs for api
2) Freecodecamp GoLang Tutorial

Connect with here ❤️ -
Twitter

Discussion (2)

Collapse
vbao profile image
csvobao

I have a dumb question? Does it necessary to learn GoLang for DevOps career? I'm still a college student.

Collapse
harkiratsm profile image
Harkirat Singh Author

Most of the cncf project are built with Golang hence you can easily contribute to those project .