Skip to content

Instantly share code, notes, and snippets.

@mt40
Last active March 14, 2017 14:11
Show Gist options
  • Save mt40/134624722b2979b452d72362c4107d8b to your computer and use it in GitHub Desktop.
Save mt40/134624722b2979b452d72362c4107d8b to your computer and use it in GitHub Desktop.
Golang cheatsheet

Array

Array type includes the type and the length. So [2]int is different from [3]int.

Type

Type binding (~ type alias)

type IntSlice []int
a := IntSlice{1, 2}

However, IntSlice is different from []int. []int is the underlying type of IntSlice.

Type conversion []int(a) can be used to convert IntSlice to []int.

General

Opening brace must be on the same line

if ... {
}

Don't do this

if ...
{
}

Datatypes

interface {} // ~ java Object
bool // true/false
string
int8  int16  int32  int64
int // =int32 on 32-bit, =int64 if 64-bit OS
uint8 uint16 uint32 uint64 uintptr
uint
byte // alias for uint8
rune // alias for int32, represents a Unicode code point
float32 float64

Zero value (i.e. default value)

  • 0 for numeric types.
  • false for the boolean type.
  • "" (the empty string) for strings.

Type casting

T(v): type conversion, convert v to type T obj.(T): type assertion, obj must be interface{} (i.e. unknown type).

t := obj.(T) // if obj is not T, error
t, ok := obj.(T) // if obj is not T, ok = false

Variable declaration

Normal form:

  • var id1, id2,... type
  • var id1, id2,... type = value1, value2,...
  • var id1, id2,... = value1, value2,... (implicit type)

Short form (use with caution) (read https://golang.org/doc/effective_go.html#redeclaration):

  • id1, id2,... := value1, value2,...
var a, b int
var c, d int = 1, 2
var e, f, g = 3, 4, 5
d := 3

Initialization

new(Type) allocates memory with default value and returns its address. make(Type, args) init object of type Type (Type must be slice, map, or channel).

var p *Person = new(Person) // pointer of type Person
var s []int = make([]int, 10) // slice of int

Array and slice

Array is a value (assigning = copying). Slice is a wrapper of an array (keeps a reference to the wrapped array). (Using slice is strongly recommended because it is convenient)

var arr = [3]int{1, 2, 3, 4} // an array. Length 3 inside [] is required
arr := [...]int{1, 2, 3, 4} // same as above

slice := make([]int, 3) // a slice of {0, 0, 0}
slice = []int{1, 2, 3, 4} // a slice of array {1, 2, 3, 4}. NO length inside []
slice = arr[1:] // = []int{2, 3, 4}, slicing an array

Map

map[key Type]value Type (key can be any type that defined the equality operator (primitive types and struct))

var myMap = map[string]int {
  "one": 1,
  "two": 2
}
v := myMap["one"] // 1
v = myMap["three"] // not exist, returns zero/default value. In this case, 0
v, ok := myMap["three"] // not exist, v = 0, ok = false
delete(myMap, "two") // delete entry

If

if condition

if x < 10 {}

if init; condition

if x = 1; x < 10 {}

For

for init; condition; post for condition (~ while) for {} (loop 4ever) for id := range collection (~ for each)

for i:= 0; i < 10; i++ {}
for true {}
for {}
for key, value := range myMap {} // ~ for each

Switch

switch obj {} (no need to be const) switch {} (pseudo if-else)

switch x {
  case 1, 2:
    ...
  case arr[x] < 100:
    break // end early
  case ..
}

Type switch

switch id := obj.(type)

switch v := anything.(type) {
  case string:
    fmt.Println(v)
  case int32, int64:
    ...
  default:
    fmt.Println("unknown")
}

Function

func name(params) (return params) {}

func divide(a int, b int) (int) {}
// named return param, `rs` is init as a variable
func divide(a int, b int) (rs int) {}

Defer

defer doSth(): defer statement, schedules to run doSth() before return

func read(...) (...) {
  f, err := os.Open(file)
  ...
  defer f.Close()
  ...
  return .. // f will be closed

Struct

import "fmt"

type Person struct {
  name string
  age int
}

// Create some methods for Person
func (p Person) walk() {
}

func (p *Person) walk() {
}

p := Person{"John", 20} // auto constructor
pt := &p

fmt.Println(p.name)
fmt.Println(pt.name) // Field accessing also works with pointer

p.walk()
pt.walk() // Same as calling methods

Const/Enum

const (
  USERNAME = "a"
  PASSWORD = 123
)

Struct embedding

There is no inheritance in Go. But you can embed other types into your custom type (~ sub-classing).

type Runner struct {
	speed int
}

func (r *Runner) Run() {
	fmt.Println("run at", r.speed)
}

type Barker struct {
	volume int
}

func (b *Barker) Bark() {
	fmt.Println("bark at", b.volume)
}

type Husky struct {
	*Runner // Husky can now run
	*Barker // Husky can now bark
}

// constructor of Husky now receive 2 pointers to 2 embedded types
dog := Husky{ &Runner{10}, &Barker{2} }
	
fmt.Println(dog.speed) // can access embedded-type property
dog.Run() // can access embedded-type method
dog.Bark() // however, the receiver of the method Bark() is Barker not Husky

Goroutine

Is a lightweight thread. Keyword go

go doSth() // run doSth() concurently

Channel

A pipe that connects goroutines. Used to send and receive values.

cn = make(chan string) // channel of type string

func main() {
  cn = make(chan string) // channel of type string
  
  // send value into the channel (1)
  go func() { cn <- "ping" }() 

  // receive message from the channel
  msg := <-cn
  // Sends and receives block until both are done.
  // after receiving, func (1) will continue
}

Buffered channel allows sending multiple messages before receiving.

...
cn = make(chan string, 2)
cn <- "one"
cn <- "two"
...
msg1 := <- cn // "one"
msg2 := <- cn // "two"

init()

Each file can have 1 or more init.

Is called after all variable declarations are initialized.

Useful for setting up states, checking,...

append(slice, x...)

Append 1 or many elements to the end of the slice.

delete(map, key)

Delete an entry from the map.

copy(dest_slice, source_slice)

Copy elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment