Skip to content

Golang

CLI

go build test.go # generate binary at ./
go install test.go # generate binary at $GOBIN/bin & cache dependencies.
go run test.go # build and run

Go Proxy

Correct way to download modules.

# powershell
$env:GOPROXY = "https://goproxy.io"
$env:GO111MODULE = "on"

go get <pkg>

Go Modules

# install packages
go get <pkg> # to $GOPATH

# start a project
go mod init <name> # create go.mod, necessary for using installed modules !!!
vim main.go # edit your code, import installed modules

# run
go run main.go # run, create go.sum (validation purpose)

Example: go.mod

module test

go 1.14

require github.com/gin-gonic/gin v1.6.3

Defer

func a() {
    defer b() // called after function returns
    return 0
}

// use:
f, err = os.Open(filename)
defer f.close() // don't need to put it in the last

// LIFO order
defer func() { fmt.Println("1") }()
defer func() { fmt.Println("2") }()
defer func() { fmt.Println("3") }()
// => 321

The empty Interface

interface{} can hold values of any type.

It is used as a dynamic type in golang.

// this func accepts any param.
func describe(i interface{}) {
    fmt.Printf("(%v, %T)\n", i, i)
}

func main() {
    var i interface{} // this is a nil object.
    describe(i) // (<nil>, <nil>)

    i = 42
    describe(i) // (42, int)

    i = "hello"
    describe(i) // (hello, string)
}

Overview

package main

import "fmt"

func main() {
    /* comment */
    // also comment
    fmt.Println("hello, world")
}
go run test.go

Types

  • Pass-by-Value

    bool int float32 float64 string
    
  • Pass-by-Reference

    Pointer struct Channel interface
    

Variables

var name type // default value is 0/nil
var name [type] = value // auto
name := value // auto, usually used inside function!

var a b type
var a,b = value1, value2
var (a type1 b type2)

const name [type] = value

// itoa: a counter
const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7
            i          //8
    )
  • Local variable must be used in the same block (Declared but not used Error)
  • Global variable may not be used.

Control

  • select
  • goto
  • for...range

    // array
    nums := []int{2, 3, 4}
    for idx, num := range nums {
        fmt.Println("index:", idx, " value:", num)
    }
    
    // map
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }
    

Function

func name([param [type1], param2 [type2]]) [return type] {}

Array

var name [size]type
var name [size]type{a, b ,c}
var name [...]type{a, b ,c} // auto

// pass to function
func foo(arr [] int, size int) int {}

Pointer

var ptr *type // nil
var ptr = &a
var ptr [size]*type

// pass to function
func swap (x* int, y* int) {
    var temp int
    temp = *x
    *x = *y
    *y = temp
}

OOP

  • struct

    type name struct {
        member type
        ...
    }
    
    var tmp = name{val, ...}
    var tmp = new(name)
    
    tmp.member
    
    var ptr *name = &tmp
    ptr.member // no ->
    
  • interface

    type name interface {
        method [return_type]
        ...
    }
    
    * define method
    
      ```go
      type Circle struct {
        radius float64
      }
    
      func main() {
        var c1 Circle
        c1.radius = 10.00
        fmt.Println("Area of Circle(c1) = ", c1.getArea())
      }
    
      func (c Circle) getArea() float64 {
        return 3.14 * c.radius * c.radius
      }
    
      // c is a tmp instance 
    

Slice (dynamic array)

var slc []type
var slc []type = make([]type, len)
var slc []type{a,b,c}

slc = append(slc, d, e)

Map

// declare
var m map [key_type] val_type
m := make(map [key_type] val_type)

// assign
m[key] = val

// access
val, ok = m[key]

// del
delete(m, key)

Go Routine

In-born multi-threading support.

  • go

    func loop() {
        for i:=0; i<10; i++ {
            fmt.Printf("%d ", i)
        }
    }
    
    func main() {
        go loop()
        go loop()
        time.Sleep(time.Second)
    }
    
  • chan

    channels are like pipes for message passing.

    ch := make(chan int)
    var ch chan int = make(chan int)
    
    ch <- message
    out, ok = <- ch
    
    // example
    var complete chan int = make(chan int)
    
    func loop() {
        for i := 0; i < 10; i++ {
            fmt.Printf("%d ", i)
        }
        complete <- 0
    }
    
    func main() {
        go loop()
        <- complete // 直到线程跑完, 取到消息. main在此阻塞住
    }
    
  • select