Golang - all you need to know

Golang - all you need to know

This is a complete list of examples of all the basic programming concepts of golang.

basic golang program structure

package main

import (
  "fmt"
)

func main(){
    fmt.Println("Hello World!")
}

to mark the entry point of the application, we must define a function main in a package main.

Running & building a go program

go run main.go

Build a go program into object code

go build

When we run the application - it looks for the package main and executes the function func main. If not present, the application will not run.

Importing packages

import "fmt"

import (
  "fmt"
  "math"
)

// alias
import r "math/rand"
// use r.Intn() instead of rand.Intn()

Define variables

// define var then assign value
var num1 int
num1 = 5

// define var and assign in same line
var num2 uint64 = 12345

// define var, infer type and assign
num3 := 3.14

// bool var
myVar := true

// use ' for single character
charVar := 'a'

// use " for strings
strVar := "some nice string here"

// multiline string
str := `Multiline
string`

// defining constants
const MAX int = 50

// public variable
var SomeVar int = 5

// private variable
var someVar2 int = 6
fmt.Print("Hello World")

fmt.Println("Hello Earth")

fmt.Printf("Hello %s", "Mars")
// prints Hello Mars

fmt.Printf("There are %v months in a year", 12)


// reading a string from stdin
var name string
fmt.Scanf("%s", &name)

var num int
fmt.Scanf("%d", &num)

Arithmetic Calculations

a = 1+2
b = 4-3
c = 10/5
d = 2*3
e = 54%3

type conversion

piInt := int(3.14)

numF := float(22)

numStr := fmt.Sprintf("%v", numF)

// for string to num refer strconv ParseInt and ParseFloat

Conditional statements

// simple if, else if, else
name := "mg"
if name == "mridul"{
  fmt.Println("Name is Mridul")
}else if name == "mg"{
  fmt.Println("Hi MG!")
}else{
  fmt.Println("I dont know you")
}

num := 2
switch num{
  case 1:
    fmt.Println("one")
  case 2:
    fmt.Println("two")
  default:
    fmt.Println("That number is too big")
}

// multiple conditions
if name == "mg" && age == 22{
  fmt.Println("Correct info")
}

if name == "mg" || name == "mridul"{
  fmt.Println("Hi")
}

Arrays and Slices

arrays - fixed length lists slices - length is not fixed, can be modified

// array with size 5
numbers := [5]int{0, 0, 0, 0, 0}

// slice with variable size
slice := []int{2, 3, 4}

nums := [5,6,7]
nums[0] = 9
fmt.Printf("%v", nums)

var numbers int[] = {6,4,2,1}
num[3] = 0
fmt.Printf("%v", numbers)

// operations 
append(numbers, 9)

// get length
len(numbers)

// delete operation here
func RemoveIndex(s []string, index int) []string {
    return append(s[:index], s[index+1:]...)
}

// usage od RemoveIndex
strSlice = RemoveIndex(strSlice, 3)

Loop

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

// missing while?
for i<20{
  fmt.Println(i)
  i+=1
}

// infinite loop
for {
  // infinite loop
  if i == 23{
    continue
  }

  fmt.Println(i)

  if i == 25{
    break
  }
}

nums := [5, 10, 15, 20, 26]
for i, val := range nums{
  fmt.Printf("index: %d value: %d\n",i, val)
}

// ignore index
for _, v := range nums{
  fmt.Println(v)
}

Functions

func main(){
  num := add(41, 2)

  num2, num3 := divMod(23,7)
}

func add(n1 int, n2 int) int{
  return n1 + n2
}

// return multiple values
func divMod(n1 int, n2 int) (int,int){
  return int(n1/n2), n1%n2
}

// named return 
func split(sum int) (x, y int) {
  x = sum * 4 / 9
  y = sum - x
  return
}

// lambda function
myfunc := func() bool {
  return x > 10
}

Recursion

func factorial(n int) int{
  if n == 0{
    return 1
  }

  return n * factorial(n-1)
}

func main(){
  sixF := factorial(6)
}

Structs

type Vertex struct {
  X int
  Y int
}

func main() {
  // v := Vertex{4, 5}
  v := Vertex{X: 1, Y: 2}

  v.X = 8
  fmt.Println(v.X, v.Y)
}

// tags
type Book struct {
    Pages   []int      `json:"pages"`
}

Attach functions to structs

type circle struct{
  radius int
}

func (c circle) Area() float32{
  return 3.14 * float32(c.radius) * float32(c.radius)
}

func main(){
  c1 := circle{radius: 2}
  area := c1.Area()
  fmt.Println(area)
}

Maps

// create a map
m := make(map[string]int)

// n := map[string]int{"foo": 1, "bar": 2}

// assign values to keys
m["n1"] = 7
m["n2"] = 13

// print entire map
fmt.Printf("map: %+v", m)

// get length
len(m)

// delete key
delete(m, "k2")

// ok = true key was present
_val, ok := m["k2"]

Pointers

func main () {
  num := 5
  updateValue(&num)
  fmt.Println("Value is", num)
}

func updateValue (a *int) {
  *a = 234
}

Json marshal & unmarshal

// import json
import "encoding/json"

// marshal slice
slcD := []string{"apple", "peach", "pear"}
slcB, _ := json.Marshal(slcD)

// marshal map
mapD := map[string]int{"apple": 5, "lettuce": 7}
mapB, _ := json.Marshal(mapD)

// marshal struct
type response1 struct {
    Page   int
    Fruits []string
}
res1D := &response1{
        Page:   1,
        Fruits: []string{"apple", "peach", "pear"}}
res1B, _ := json.Marshal(res1D)

// unmarshal string to slice/map/struct
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)

var dat map[string]interface{}
if err := json.Unmarshal(byt, &dat); err != nil {
    panic(err)
}

Interfaces with structs

type Shape interface {
  Area() float64
}

type Rectangle struct {
  Length, Width float64
}

type Circle struct {
  radius float64
}

func (r Circle) Area() float64 {
  return 3.14 * r.radius * r.radius
}

func (r Rectangle) Area() float64 {
  return r.Length * r.Width
}

Basic string operations

import (
    "fmt"
    s "strings"
)

var p = fmt.Println

func main() {

    p("Contains:  ", s.Contains("test", "es"))
    p("Count:     ", s.Count("test", "t"))
    p("HasPrefix: ", s.HasPrefix("test", "te"))
    p("HasSuffix: ", s.HasSuffix("test", "st"))
    p("Index:     ", s.Index("test", "e"))
    p("Join:      ", s.Join([]string{"a", "b"}, "-"))
    p("Repeat:    ", s.Repeat("a", 5))
    p("Replace:   ", s.Replace("foo", "o", "0", -1))
    p("Replace:   ", s.Replace("foo", "o", "0", 1))
    p("Split:     ", s.Split("a-b-c-d-e", "-"))
    p("ToLower:   ", s.ToLower("TEST"))
    p("ToUpper:   ", s.ToUpper("test"))
    p()

    p("Len: ", len("hello"))
    p("Char:", "hello"[1])
    p("Slicing :", "hello"[1:2])
}

Basic file operations

basic stuff

// create file
newFile, _ := os.Create("test.txt")

// rename file
_ = os.Rename("file1", "file2")

// remove file
_ = os.Remove("test.txt")

write to file

import (
    "io/ioutil"
    "log"
)

func main() {
    err := ioutil.WriteFile("test.txt", []byte("Hi\n"), 0666)
    if err != nil {
        log.Fatal(err)
    }
}

read file

import (
    "log"
    "io/ioutil"
)

func main() {
    // Read file to byte slice
    data, err := ioutil.ReadFile("test.txt")
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("Data read: %s\n", data)
}

Get file info

import (
    "fmt"
    "log"
    "os"
)

var (
    fileInfo os.FileInfo
    err      error
)

func main() {
    // Stat returns file info. It will return
    // an error if there is no file.
    fileInfo, err = os.Stat("test.txt")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("File name:", fileInfo.Name())
    fmt.Println("Size in bytes:", fileInfo.Size())
    fmt.Println("Permissions:", fileInfo.Mode())
    fmt.Println("Last modified:", fileInfo.ModTime())
    fmt.Println("Is Directory: ", fileInfo.IsDir())
    fmt.Printf("System interface type: %T\n", fileInfo.Sys())
    fmt.Printf("System info: %+v\n\n", fileInfo.Sys())
}

Make simple http server in golang

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", HelloServer)
    http.ListenAndServe(":8080", nil)
}

func HelloServer(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}

Go routines (basic)

func say(s string) {
    time.Sleep(100 * time.Millisecond)
    fmt.Println(s)
}

func main() {
    go say("world")
    say("hello")
}

// make a new thread
// go xyz()

Error handling in golang

// we return error with output
func divideNum(n1 float32, n2 float32) (float32, error){
  if n2==0{
    return 0, fmt.Errorf("Divide by 0")
  }
  return n1/n2, nil
}

func  main(){
  val, err := divideNum(2,1)
  fmt.Printf("%v %v\n", val, err)
  val, err = divideNum(4,0)
  fmt.Printf("%v %v\n", val, err)
}

// checking for error 
if err != nil{
  panic("got error, will die")
}

Panic

// When we get runtime error - golang panics
func main(){
  a,b := 5,0
    _ = a/b
}

defer and recover

// defer runs after execution of function
func main(){
  defer func(){
    fmt.Println("world")
  }()
  fmt.Print("hello ")
}

// using recover
func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic. Error :", r)
        }
    }()
    panic("Some runtime error here")
}