Go by Example

From https://gobyexample.com/

Hello World

1
2
3
4
5
6
7
package main

import "fmt"

func main() {
fmt.Println("hello world")
}

Values

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
// golang
fmt.Println("go" + "lang")
// 1+1 = 2
fmt.Println("1+1 =", 1+1)
// 7.0/3/0 = 2.3333333333333335
fmt.Println("7.0/3.0 =", 7.0/3.0)
// false
fmt.Println(true && false)
// true
fmt.Println(true || false)
// false
fmt.Println(!true)
}

Variables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
// initial
var a string = "initial"
fmt.Println(a)

// 1 2
var b, c int = 1, 2
fmt.Println(b, c)

// true
var d = true
fmt.Println(d)

// 0
var e int
fmt.Println(e)

// short
f := "short"
fmt.Println(f)
}

Constants

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"
import "math"

const s string = "constant"

func main() {
// constant
fmt.Println(s)

const n = 500000000
const d = 3e20 / n

// 6e+11
fmt.Println(d)
// 600000000000
fmt.Println(int64(d))
// -0.28470407323754404
fmt.Println(math.Sin(n))
}

For

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import "fmt"

func main() {
// 1 \n 2 \n 3
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}

// 7 \n 8 \n 9
for j := 7; j <= 9; j++ {
fmt.Println(j)
}

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

// 1 \n 3 \n 5
for n := 0; n <= 5; n++ {
if n%2 == 0 {
continue
}
fmt.Println(n)
}
}

If / Else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import "fmt"

func main() {
// 7 is odd
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}

// 8 is divisible by 4
if 8%4 == 0 {
fmt.Println("8 is divisible by 4")
}

// 9 has 1 digit
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
}

Switch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main

import "fmt"
import "time"

func main() {
// Write 2 as two
i := 2
fmt.Print("Write ", i, " as ")
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}

// It's a weekday
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("It's the weekend")
default:
fmt.Println("It's a weekday")
}

// It's after noon
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}

whatAmI := func(i interface{}) {
switch t := i.(type) {
case bool:
fmt.Println("I'm a bool")
case int:
fmt.Println("I'm an int")
default:
fmt.Printf("Don't know type %T\n", t)
}
}
// I'm a bool
whatAmI(true)
// I'm an int
whatAmI(1)
// Don't know type string
whatAmI("hey")
}

Arrays

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

func main() {
// emp: [0 0 0 0 0]
var a [5]int
fmt.Println("emp:", a)

a[4] = 100
// set: [0 0 0 0 100]
fmt.Println("set:", a)
// get: 100
fmt.Println("get:", a[4])
// len: 5
fmt.Println("len:", len(a))

b := [5]int{1, 2, 3, 4, 5}
// dcl: [1 2 3 4 5]
fmt.Println("dcl:", b)
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
// 2d: [[0 1 2] [1 2 3]]
fmt.Println("2d: ", twoD)
}

Slices

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package main

import "fmt"

func main() {
// emp: [ ]
s := make([]string, 3)
fmt.Println("emp:", s)

s[0] = "a"
s[1] = "b"
s[2] = "c"
// set: [a b c]
fmt.Println("set:", s)
// get: c
fmt.Println("get:", s[2])
// len: 3
fmt.Println("len:", len(s))

s = append(s, "d")
s = append(s, "e", "f")
// apd: [a b c d e f]
fmt.Println("apd:", s)

c := make([]string, len(s))
copy(c, s)
// cpy: [a b c d e f]
fmt.Println("cpy:", c)

// sl1: [c d e]
l := s[2:5]
fmt.Println("sl1:", l)

// sl2: [a b c d e]
l = s[:5]
fmt.Println("sl2:", l)

// sl3: [c d e f]
l = s[2:]
fmt.Println("sl3:", l)

// dcl: [g h i]
t := []string{"g", "h", "i"}
fmt.Println("dcl:", t)

// 2d: [[0] [1 2] [2 3 4]]
twoD := make([][]int, 3)
for i := 0; i < 3; i++ {
innerLen := i + 1
twoD[i] = make([]int, innerLen)
for j := 0; j < innerLen; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d: ", twoD)
}

Maps

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import "fmt"

func main() {
m := make(map[string]int)

// map: map[k1:7 k2:13]
m["k1"] = 7
m["k2"] = 13
fmt.Println("map:", m)

// v1: 7
// len: 2
v1 := m["k1"]
fmt.Println("v1: ", v1)
fmt.Println("len:", len(m))

// map: map[k1:7]
delete(m, "k2")
fmt.Println("map:", m)

// prs: false
_, prs := m["k2"]
fmt.Println("prs:", prs)

// map: map[foo:1 bar:2]
n := map[string]int{"foo": 1, "bar": 2}
fmt.Println("map:", n)
}

Range

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import "fmt"

func main() {
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
// sum: 9
fmt.Println("sum:", sum)

// index: 1
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
}
}

kvs := map[string]string{"a": "apple", "b": "banana"}
// a -> apple
// b -> banana
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
// key: a
// key: b
for k := range kvs {
fmt.Println("key:", k)
}
// 0 103
// 1 111
for l, c := range "go" {
fmt.Println(l, c)
}
}

Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func plus(a int, b int) int {
return a + b
}

func plusPlus(a, b, c int) int {
return a + b + c
}
func main() {
// 1+2 = 3
res := plus(1, 2)
fmt.Println("1+2 =", res)
// 1+2+3 = 6
res = plusPlus(1, 2, 3)
fmt.Println("1+2+3 =", res)
}

Multiple Return Values

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func vals() (int, int) {
return 3, 7
}

func main() {
a, b := vals()
// 3
fmt.Println(a)
// 7
fmt.Println(b)

_, c := vals()
// 7
fmt.Println(c)
}

Variadic Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}

func main() {
// [1 2] 3
sum(1, 2)
// [1 2 3] 6
sum(1, 2, 3)
// [1 2 3 4] 10
nums := []int{1, 2, 3, 4}
sum(nums...)
}

Closures

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import "fmt"

func intSeq() func() int {
i := 0
return func() int {
i += 1
return i
}
}

func main() {
nextInt := intSeq()

// 1
fmt.Println(nextInt())
// 2
fmt.Println(nextInt())
// 3
fmt.Println(nextInt())

// 1
newInt := intSeq()
fmt.Println(newInt())
}

Recursion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}

func main() {
// 5040
fmt.Println(fact(7))
}

Pointers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func zeroval(val int) {
val = 0
}

func zeroptr(ptr *int) {
*ptr = 0
}

func main() {
// initlal: 1
i := 1
fmt.Println("initlal:", i)

// zeroval: 1
zeroval(i)
fmt.Println("zeroval:", i)

// zeroprt: 0
zeroptr(&i)
fmt.Println("zeroptr:", i)

// pointer: 0xc082056038
fmt.Println("pointer:", &i)
}

Structs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

type person struct {
name string
age int
}

func main() {
// {Bob 20}
fmt.Println(person{"Bob", 20})
// {Alice 30}
fmt.Println(person{name: "Alice", age: 30})
// {Fred 0}
fmt.Println(person{name: "Fred"})
// &{Ann 40}
fmt.Println(&person{name: "Ann", age: 40})
// Sean
s := person{name: "Sean", age: 50}
fmt.Println(s.name)
// 50
sp := &s
fmt.Println(sp.age)
// 52
sp.age = 52
fmt.Println(sp.age)
}

Methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

type rect struct {
width, height int
}

func (r *rect) area() int {
return r.width * r.height
}

func (r rect) perim() int {
return 2*r.width + 2*r.height
}

func main() {
// area: 50
// perim: 30
r := rect{width: 10, height: 5}
fmt.Println("area:", r.area())
fmt.Println("perim:", r.perim())

// area: 50
// perim: 30
rp := &r
fmt.Println("area:", rp.area())
fmt.Println("perim:", rp.perim())
}

Interfaces

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package main

import "fmt"
import "math"

type geometry interface {
area() float64
perim() float64
}

type rect struct {
width, height float64
}

type circle struct {
redius float64
}

func (r rect) area() float64 {
return r.width * r.height
}

func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}

func (c circle) area() float64 {
return math.Pi * c.redius * c.redius
}

func (c circle) perim() float64 {
return 2 * math.Pi * c.redius
}

func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}

func main() {
r := rect{width: 3, height: 4}
c := circle{redius: 5}

// {3 4}
// 12
// 14
measure(r)
// {5}
// 78.53981633974483
// 31.41592653589793
measure(c)
}

Errors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main

import "fmt"
import "errors"

func f1(arg int) (int, error) {
if arg == 42 {
return -1, errors.New("can't work with 42")
}
return arg + 3, nil
}

type argError struct {
arg int
prob string
}

func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

func f2(arg int) (int, error) {
if arg == 42 {
return -1, &argError{arg, "can't work with it"}
}
return arg + 3, nil
}

func main() {
// f1 worked: 10
// f1 failed: cant't work with 42
for _, i := range []int{7, 42} {
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}
// f2 worked: 10
// f2 failed: 42 - can't work with it
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 failed:", e)
} else {
fmt.Println("f2 worked:", r)
}
}
// 42
// can't work with it
_, e := f2(42)
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}

Goroutines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
}

func main() {
f("direct")
go f("goroutine")
go func(msg string) {
fmt.Println(msg)
}("going")
var input string
fmt.Scanln(&input)
fmt.Println("done")
// direct : 0
// direct : 1
// direct : 2
// goroutine : 0
// going
// goroutine : 1
// goroutine : 2
// <enter>
// done
}

Channels

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
messages := make(chan string)
go func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
// ping
}

Channel Buffering

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
messages := make(chan string, 2)

messages <- "buffered"
messages <- "channel"

// buffered
fmt.Println(<-messages)
// channel
fmt.Println(<-messages)
}

Channel Synchronization

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"
import "time"

func worker(done chan bool) {
fmt.Print("working...")
time.Sleep(time.Second)
fmt.Println("done")
done <- true
}

func main() {
done := make(chan bool, 1)
go worker(done)
<-done
// working...done
}

Channel Directions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

func ping(pings chan<- string, msg string) {
pings <- msg
}

func pong(pings <-chan string, pongs chan<- string) {
msg := <-pings
pongs <- msg
}

func main() {
pings := make(chan string, 1)
pongs := make(chan string, 1)
ping(pings, "passed message")
pong(pings, pongs)
fmt.Println(<-pongs)
// passed message
}

Select

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import "fmt"
import "time"

func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
// received one
// reveived two
}

Timeouts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"
import "time"

func main() {
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()
// timeout 1
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout 1")
}

c2 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c2 <- "result 2"
}()
// result 2
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(time.Second * 3):
fmt.Println("timeout 2")
}
}

Non-Blocking Channel Operations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import "fmt"

func main() {
messages := make(chan string)
signals := make(chan bool)

select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}

msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}

select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
// no message received
// no message sent
// no activity
}

Closing Channels

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import "fmt"

func main() {
jobs := make(chan int, 5)
done := make(chan bool)

go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()

for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent jobs", j)
}
close(jobs)
fmt.Println("sent all jobs")

<-done
// sent jobs 1
// sent jobs 2
// sent jobs 3
// sent all jobs
// received job 1
// received job 2
// received job 3
// received all jobs
}

Range over Channels

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)

for elem := range queue {
fmt.Println(elem)
}
// one
// two
}

Timers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"
import "time"

func main() {
timer1 := time.NewTimer(time.Second * 2)

<-timer1.C
fmt.Println("Timer 1 expired")

timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
fmt.Println("Timer 2 expired")
}()
stop2 := timer2.Stop()
if stop2 {
fmt.Println("Timer 2 stoped")
}
// Timer 1 expired
// Timer 2 stoped
}

Tickers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"
import "time"

func main() {
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()

time.Sleep(time.Millisecond * 1600)
ticker.Stop()
fmt.Println("Ticker stopped")
// Tick at 2017-01-11 20:29:24.2333714 +0800 CST
// Tick at 2017-01-11 20:29:24.735118 +0800 CST
// Tick at 2017-01-11 20:29:25.2342189 +0800 CST
// Ticker stopped
}

Worker Pools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import "fmt"
import "time"

func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}

func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)

for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}

for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)

for a := 1; a <= 5; a++ {
<-results
}
// worker 3 started job 1
// worker 1 started job 2
// worker 2 started job 3
// worker 3 finished job 1
// worker 3 started job 4
// worker 2 finished job 3
// worker 2 started job 5
// worker 1 finished job 2
// worker 3 finished job 4
// worker 2 finished job 5
}

Rate Limiting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main

import "fmt"
import "time"

func main() {
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)

limiter := time.Tick(time.Millisecond * 200)

for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
}

burstyLimiter := make(chan time.Time, 3)

for i := 0; i < 3; i++ {
burstyLimiter <- time.Now()
}

go func() {
for t := range time.Tick(time.Millisecond * 200) {
burstyLimiter <- t
}
}()

burstyRequests := make(chan int, 5)
for i := 1; i <= 5; i++ {
burstyRequests <- i
}

close(burstyRequests)
for req := range burstyRequests {
<-burstyLimiter
fmt.Println("request", req, time.Now())
}
// request 1 2017-01-26 20:50:07.6919452 +0800 CST
// request 2 2017-01-26 20:50:07.8917206 +0800 CST
// request 3 2017-01-26 20:50:08.0921071 +0800 CST
// request 4 2017-01-26 20:50:08.2925082 +0800 CST
// request 5 2017-01-26 20:50:08.4923916 +0800 CST
// request 1 2017-01-26 20:50:08.4923916 +0800 CST
// request 2 2017-01-26 20:50:08.4940956 +0800 CST
// request 3 2017-01-26 20:50:08.4940956 +0800 CST
// request 4 2017-01-26 20:50:08.694855 +0800 CST
// request 5 2017-01-26 20:50:08.8945135 +0800 CST
}

Atomic Counters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"
import "time"
import "sync/atomic"

func main() {
var ops uint64 = 0
for i := 0; i < 50; i++ {
go func() {
for {
atomic.AddUint64(&ops, 1)
time.Sleep(time.Millisecond)
}
}()
}
time.Sleep(time.Second)
opsFinal := atomic.LoadUint64(&ops)
// ops 31202
fmt.Println("ops", opsFinal)
}

Mutexes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main

import (
"fmt"
"math/rand"
"sync"
"sync/atomic"
"time"
)

func main() {
var state = make(map[int]int)

var mutex = &sync.Mutex{}

var readOps uint64 = 0
var writeOps uint64 = 0

for r := 0; r < 100; r++ {
go func() {
total := 0
for {
key := rand.Intn(5)
mutex.Lock()
total += state[key]
mutex.Unlock()
atomic.AddUint64(&readOps, 1)

time.Sleep(time.Millisecond)
}
}()
}

for w := 0; w < 10; w++ {
go func() {
for {
key := rand.Intn(5)
val := rand.Intn(100)
mutex.Lock()
state[key] = val
mutex.Unlock()
atomic.AddUint64(&writeOps, 1)
time.Sleep(time.Millisecond)
}
}()
}

time.Sleep(time.Second)

// readOps: 61609
readOpsFinal := atomic.LoadUint64(&readOps)
fmt.Println("readOps:", readOpsFinal)
// writeOps: 6197
writeOpsFinal := atomic.LoadUint64(&writeOps)
fmt.Println("writeOps:", writeOpsFinal)
// state: map[1:91 0:88 2:35 3:92 4:20]
mutex.Lock()
fmt.Println("state:", state)
mutex.Unlock()
}

Stateful Goroutines

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package main

import (
"fmt"
"math/rand"
"sync/atomic"
"time"
)

type readOp struct {
key int
resp chan int
}

type writeOp struct {
key int
val int
resp chan bool
}

func main() {
var readOps uint64 = 0
var writeOps uint64 = 0

reads := make(chan *readOp)
writes := make(chan *writeOp)

go func() {
var state = make(map[int]int)
for {
select {
case read := <-reads:
read.resp <- state[read.key]
case write := <-writes:
state[write.key] = write.val
write.resp <- true
}
}
}()

for r := 0; r < 100; r++ {
go func() {
for {
read := &readOp{
key: rand.Intn(5),
resp: make(chan int)}
reads <- read
<-read.resp
atomic.AddUint64(&readOps, 1)
time.Sleep(time.Millisecond)
}
}()
}

for w := 0; w < 10; w++ {
go func() {
for {
write := &writeOp{
key: rand.Intn(5),
val: rand.Intn(100),
resp: make(chan bool)}
writes <- write
<-write.resp
atomic.AddUint64(&writeOps, 1)
time.Sleep(time.Millisecond)
}
}()
}

time.Sleep(time.Second)

// readOps: 59638
readOpsFinal := atomic.LoadUint64(&readOps)
fmt.Println("readOps:", readOpsFinal)
// writeOps: 6562
writeOpsFinal := atomic.LoadUint64(&writeOps)
fmt.Println("writeOps:", writeOpsFinal)
}

Sorting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"
import "sort"

func main() {
// Strings: [a b c]
strs := []string{"c", "a", "b"}
sort.Strings(strs)
fmt.Println("Strings:", strs)
// Ints: [2 4 7]
ints := []int{7, 2, 4}
sort.Ints(ints)
fmt.Println("Ints:", ints)
// Sorted: true
s := sort.IntsAreSorted(ints)
fmt.Println("Sorted:", s)
}

Sorting by Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"
import "sort"

type ByLength []string

func (s ByLength) Len() int {
return len(s)
}
func (s ByLength) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s ByLength) Less(i, j int) bool {
return len(s[i]) < len(s[j])
}

func main() {
fruits := []string{"peach", "banana", "kiwi"}
sort.Sort(ByLength(fruits))
fmt.Println(fruits)
// [kiwi peach banana]
}

Panic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "os"

func main() {
// panic: a problem
panic("a problem")

// goroutine 1 [running]:
// panic(0x491380, 0xc082008200)
// C:/Go/src/runtime/panic.go:481 +0x3f4
// main.main()
// D:/gobyexample/src/t.go:7 +0x6c
// exit status 2
_, err := os.Create("./tmp/file")
if err != nil {
panic(err)
}
}

Defer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "os"
import "fmt"

func main() {
f := createFile("./tmp/defer.txt")
defer closeFile(f)
writeFile(f)
// creating
// writing
// closing
}

func createFile(p string) *os.File {
fmt.Println("creating")
f, err := os.Create(p)
if err != nil {
panic(err)
}
return f
}

func writeFile(f *os.File) {
fmt.Println("writing")
fmt.Fprintln(f, "data")
}

func closeFile(f *os.File) {
fmt.Println("closing")
f.Close()
}

Collection Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main

import "fmt"
import "strings"

func Index(vs []string, t string) int {
for i, v := range vs {
if v == t {
return i
}
}
return -1
}

func Include(vs []string, t string) bool {
return Index(vs, t) >= 0
}

func Any(vs []string, f func(string) bool) bool {
for _, v := range vs {
if f(v) {
return true
}
}
return false
}

func All(vs []string, f func(string) bool) bool {
for _, v := range vs {
if !f(v) {
return false
}
}
return true
}

func Filter(vs []string, f func(string) bool) []string {
vsf := make([]string, 0)
for _, v := range vs {
if f(v) {
vsf = append(vsf, v)
}
}
return vsf
}

func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
for i, v := range vs {
vsm[i] = f(v)
}
return vsm
}

func main() {
// 2
var strs = []string{"peach", "apple", "pear", "plum"}
fmt.Println(Index(strs, "pear"))
// false
fmt.Println(Include(strs, "grape"))
// true
fmt.Println(Any(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
// false
fmt.Println(All(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
// [peach apple pear]
fmt.Println(Filter(strs, func(v string) bool {
return strings.Contains(v, "e")
}))
// [PEACH APPLE PEAR PLUM]
fmt.Println(Map(strs, strings.ToUpper))
}

String Functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import "fmt"
import 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])
// Contains: true
// Count: 2
// HasPrefix: true
// HasSuffix: true
// Index: 1
// Join: a-b
// Repeat: aaaaa
// Replace: f00
// Replace: f0o
// Split: [a b c d e]
// ToLower: test
// ToUpper: TEST
//
// Len: 5
// Char: 101
}

String Formatting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package main

import "fmt"
import "os"

type point struct {
x, y int
}

func main() {
p := point{1, 2}
// {1 2}
fmt.Printf("%v\n", p)
// {x:1 y:2}
fmt.Printf("%+v\n", p)
// main.point{x:1, y:2}
fmt.Printf("%#v\n", p)
// main.point
fmt.Printf("%T\n", p)
// true
fmt.Printf("%t\n", true)
// 123
fmt.Printf("%d\n", 123)
// 1110
fmt.Printf("%b\n", 14)
// !
fmt.Printf("%c\n", 33)
// 1c8
fmt.Printf("%x\n", 456)
// 78.900000
fmt.Printf("%f\n", 78.9)
// 1.234000e+08
fmt.Printf("%e\n", 123400000.0)
// 1.234000E+08
fmt.Printf("%E\n", 123400000.0)
// "string"
fmt.Printf("%s\n", "\"string\"")
// "\"string\""
fmt.Printf("%q\n", "\"string\"")
// 6865782074686973
fmt.Printf("%x\n", "hex this")
// 0xc082008260
fmt.Printf("%p\n", &p)
// | 12| 345|
fmt.Printf("|%6d|%6d|\n", 12, 345)
// | 1.20| 3.45|
fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)
// |1.20 |3.45 |
fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)
// | foo| b|
fmt.Printf("|%6s|%6s|\n", "foo", "b")
// |foo |b |
fmt.Printf("|%-6s|%-6s|\n", "foo", "b")
// a string
s := fmt.Sprintf("a %s", "string")
fmt.Println(s)
// an error
fmt.Fprintf(os.Stderr, "an %s\n", "error")
}

Regular Expressions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import "fmt"
import "bytes"
import "regexp"

func main() {
// true
match, _ := regexp.MatchString("p([a-z]+)ch", "peach")
fmt.Println(match)
// true
r, _ := regexp.Compile("p([a-z]+)ch")
fmt.Println(r.MatchString("peach"))
// peach
fmt.Println(r.FindString("peach punch"))
// [0 5]
fmt.Println(r.FindStringIndex("peach punch"))
// [peach ea]
fmt.Println(r.FindStringSubmatch("peach punch"))
// [0 5 1 3]
fmt.Println(r.FindStringSubmatchIndex("peach punch"))
// [peach punch pinch]
fmt.Println(r.FindAllString("peach punch pinch", -1))
// [[0 5 1 3] [6 11 7 9] [12 17 13 15]]
fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))
// [peach punch]
fmt.Println(r.FindAllString("peach punch pinch", 2))
// true
fmt.Println(r.Match([]byte("peach")))
// p([a-z]+)ch
r = regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r)
// a <fruit>
fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
// a PEACH
in := []byte("a peach")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out))
}

JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main

import "os"
import "fmt"
import "encoding/json"

type Response1 struct {
Page int
Fruits []string
}

type Response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}

func main() {
// true
bolB, _ := json.Marshal(true)
fmt.Println(string(bolB))
// 1
intB, _ := json.Marshal(1)
fmt.Println(string(intB))
// 2.34
fltB, _ := json.Marshal(2.34)
fmt.Println(string(fltB))
// "gopher"
strB, _ := json.Marshal("gopher")
fmt.Println(string(strB))
// ["apple", "peach", "pear"]
slcD := []string{"apple", "peach", "pear"}
slcB, _ := json.Marshal(slcD)
fmt.Println(string(slcB))
// {"apple":5,"lettuce":7}
mapD := map[string]int{"apple": 5, "lettuce": 7}
mapB, _ := json.Marshal(mapD)
fmt.Println(string(mapB))
// {"Page":1,"Fruits":["apple","peach","pear"]}
res1D := &Response1{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res1B, _ := json.Marshal(res1D)
fmt.Println(string(res1B))
// {"page":1,"fruits":["apple","peach","pear"]}
res2D := &Response2{
Page: 1,
Fruits: []string{"apple", "peach", "pear"}}
res2B, _ := json.Marshal(res2D)
fmt.Println(string(res2B))
// map[num:6.13 strs:[a b]]
byt := []byte(`{"num": 6.13, "strs": ["a", "b"]}`)
var dat map[string]interface{}
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Println(dat)
// 6.13
num := dat["num"].(float64)
fmt.Println(num)
// a
strs := dat["strs"].([]interface{})
str1 := strs[0].(string)
fmt.Println(str1)
// {1 [apple peach]}
// apple
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := Response2{}
json.Unmarshal([]byte(str), &res)
fmt.Println(res)
fmt.Println(res.Fruits[0])
// {"apple":5,"lettuce":7}
enc := json.NewEncoder(os.Stdout)
d := map[string]int{"apple": 5, "lettuce": 7}
enc.Encode(d)
}

Time

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main

import "fmt"
import "time"

func main() {
p := fmt.Println

now := time.Now()
// 2017-01-27 17:10:19.5024236 +0800 CST
p(now)

then := time.Date(2017, 1, 11, 17, 03, 58, 651387237, time.UTC)
// 2017-01-11 17:03:58.651387237 +0000 UTC
p(then)

// 2017
p(then.Year())
// January
p(then.Month())
// 11
p(then.Day())
// 17
p(then.Hour())
// 3
p(then.Minute())
// 58
p(then.Second())
// 651387237
p(then.Nanosecond())
// UTC
p(then.Location())

// Wednesday
p(then.Weekday())

// true
p(then.Before(now))

// false
p(then.After(now))

// false
p(then.Equal(now))

diff := now.Sub(then)
// 376h6m20.851036363s
p(diff)

// 376.1057919545453
p(diff.Hours())
// 22566.347517272716
p(diff.Minutes())
// 1.353980851036363e+06
p(diff.Seconds())
// 1353980851036363
p(diff.Nanoseconds())

// 2017-01-27 09:10:19.5024236 +0000 UTC
p(then.Add(diff))
// 2016-12-27 00:57:37.800350874 +0000 UTC
p(then.Add(-diff))
}

Epoch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"
import "time"

func main() {
now := time.Now()
secs := now.Unix()
nanos := now.UnixNano()
// 2017-01-27 17:17:49.0002965 +0800 CST
fmt.Println(now)

millis := nanos / 1000000
// 1485508669
fmt.Println(secs)
// 1485508669000
fmt.Println(millis)
// 1485508669000296500
fmt.Println(nanos)

// 2017-01-27 17:17:49 +0800 CST
fmt.Println(time.Unix(secs, 0))
// 2017-01-27 17:17:49.0002965 +0800 CST
fmt.Println(time.Unix(0, nanos))
}

Time Formatting / Parsing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import "fmt"
import "time"

func main() {
p := fmt.Println

t := time.Now()
// 2017-01-27T17:29:51+08:00
p(t.Format(time.RFC3339))

t1, e := time.Parse(time.RFC3339, "2017-01-11T17:23:23+00:00")
// 2017-01-11 17:23:23 +0000 +0000
p(t1)

// 5:51PM
p(t.Format("3:05PM"))
// Fri Jan 27 17:53:53 2017
p(t.Format("Mon Jan _2 15:05:05 2006"))
// 2017-01-27T17:53:53.075142+08:00
p(t.Format("2006-01-02T15:05:05.999999-07:00"))
form := "3 05 PM"
t2, e := time.Parse(form, "8 51 PM")
// 0000-01-01 20:00:51 +0000 UTC
p(t2)

// 2017-01-27T17:39:23-00:00
fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())

ansic := "Mon Jan _2 15:05:05 2006"
_, e = time.Parse(ansic, "8:51PM")
// parsing time "8:51PM" as "Mon Jan _2 15:05:05 2006": cannot parse "8:51PM" as "Mon"
p(e)
}

In this Case:
1609-09-12 19:02:35 PM +03:00 Sep Sat PDT

Type Placeholder Value
Year 2006 1609
Year 06 09
Month 01 09
Month 1 9
Month Jan Sep
Month January September
Day 02 12
Day 2 12
Week day Mon Sat
Week day Monday Saturday
Hours 03 07
Hours 3 7
Hours 15 19
Minutes 04 02
Minutes 4 2
Seconds 05 35
Seconds 5 35
AM or PM PM PM
Milliseconds .000 .123
Microseconds .000000 .123456
Nanoseconds .000000000 .123456789
Timezone offset -0700 +0300
Timezone offset -07:00 +03:00
Timezone offset Z0700 +0300
Timezone offset Z07:00 +03:00
Timezone MST PDT

Random Numbers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import "fmt"
import "time"
import "math/rand"

func main() {
// 81,87
fmt.Print(rand.Intn(100), ",")
fmt.Print(rand.Intn(100))
fmt.Println()

// 0.6645600532184904
fmt.Println(rand.Float64())

// 7.1885709359349015,7.123187485356329
fmt.Print((rand.Float64()*5)+5, ",")
fmt.Print((rand.Float64() * 5) + 5)
fmt.Println()

// 96,16
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
fmt.Print(r1.Intn(100), ",")
fmt.Print(r1.Intn(100))
fmt.Println()

// 2,16
s2 := rand.NewSource(83)
r2 := rand.New(s2)
fmt.Print(r2.Intn(100), ",")
fmt.Print(r2.Intn(100))
fmt.Println()

// 2,16
s3 := rand.NewSource(83)
r3 := rand.New(s3)
fmt.Print(r3.Intn(100), ",")
fmt.Print(r3.Intn(100))
fmt.Println()
}

Number Parsing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import "fmt"
import "strconv"

func main() {
// 1.234
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)

// 123
i, _ := strconv.ParseInt("123", 0, 64)
fmt.Println(i)

// 456
d, _ := strconv.ParseInt("0x1c8", 0, 64)
fmt.Println(d)

// 789
u, _ := strconv.ParseUint("789", 0, 64)
fmt.Println(u)

// 135
k, _ := strconv.Atoi("135")
fmt.Println(k)

// strconv.ParseInt: parsing "wat": invalid syntax
_, e := strconv.Atoi("wat")
fmt.Println(e)
}

URL Parsing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main

import "fmt"
import "net"
import "net/url"

func main() {
s := "postgres://user:pass@host.com:5432/path?k=v#f"

// postgres
u, err := url.Parse(s)
if err != nil {
panic(err)
}
fmt.Println(u.Scheme)

// user:pass
fmt.Println(u.User)
// usr
fmt.Println(u.User.Username())

p, _ := u.User.Password()
// pass
fmt.Println(p)

// host.com:5432
fmt.Println(u.Host)
host, port, _ := net.SplitHostPort(u.Host)
// host.com
fmt.Println(host)
// 5432
fmt.Println(port)

// /path
fmt.Println(u.Path)
// f
fmt.Println(u.Fragment)

// k=v
fmt.Println(u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
// map[k:[v]]
fmt.Println(m)
// v
fmt.Println(m["k"][0])
}

SHA1 Hashes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"
import "crypto/sha1"

func main() {
s := "sha1 this string"
h := sha1.New()
h.Write([]byte(s))
bs := h.Sum(nil)
// sha1 this string
fmt.Println(s)
// cf23df2207d99a74fbe169e3eba035e633b65d94
fmt.Printf("%x\n", bs)
}

Base64 Encoding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"
import b64 "encoding/base64"

func main() {
data := "abc123!?$*&()'-=@~"

sEnc := b64.StdEncoding.EncodeToString([]byte(data))
// YWJjMTIzIT8kKiYoKSctPUB+
fmt.Println(sEnc)
sDec, _ := b64.StdEncoding.DecodeString(sEnc)
// abc123!?$*&()'-=@~
fmt.Println(string(sDec))

uEnc := b64.URLEncoding.EncodeToString([]byte(data))
// YWJjMTIzIT8kKiYoKSctPUB-
fmt.Println(string(uEnc))
uDec, _ := b64.URLEncoding.DecodeString(uEnc)
// abc123!?$*&()'-=@~
fmt.Println(string(uDec))
}

Reading Files

1
2
echo 'hello' > /tmp/dat
echo 'go' >> /tmp/dat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package main

import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)

func check(e error) {
if e != nil {
panic(e)
}
}

func main() {
dat, err := ioutil.ReadFile("/tmp/dat")
check(err)
// hello
// go
fmt.Print(string(dat))

f, err := os.Open("/tmp/dat")
check(err)

b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
// 5 bytes: hello
fmt.Printf("%d bytes: %s\n", n1, string(b1))

o2, err := f.Seek(6, 0)
check(err)
b2 := make([]byte, 2)
n2, err := f.Read(b2)
check(err)
// 2 bytes @ 6: go
fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))

o3, err := f.Seek(6, 0)
check(err)
b3 := make([]byte, 2)
n3, err := io.ReadAtLeast(f, b3, 2)
check(err)
// 2 bytes @ 6: go
fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))

_, err = f.Seek(0, 0)
check(err)

r4 := bufio.NewReader(f)
b4, err := r4.Peek(5)
check(err)
// 5 bytes: hello
fmt.Printf("5 bytes: %s\n", string(b4))

f.Close()
}

Writing Files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main

import (
"bufio"
"fmt"
"io/ioutil"
"os"
)

func check(e error) {
if e != nil {
panic(e)
}
}

func main() {
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("/tmp/dat1", d1, 0644)
check(err)

f, err := os.Create("/tmp/dat2")
check(err)

defer f.Close()

d2 := []byte{115, 111, 109, 101, 10}
n2, err := f.Write(d2)
check(err)
// wrote 5 bytes
fmt.Printf("wrote %d bytes\n", n2)

n3, err := f.WriteString("writes\n")
// wrote 7 bytes
fmt.Printf("wrote %d bytes\n", n3)

f.Sync()

w := bufio.NewWriter(f)
n4, err := w.WriteString("buffered\n")
// wrote 9 bytes
fmt.Printf("wrote %d bytes\n", n4)

w.Flush()
}
1
2
3
4
5
6
7
cat /tmp/dat1
# hello
# go
cat /tmp/dat2
# some
# writes
# buffered

Line Filters

1
2
3
4
5
echo 'hello' > /tmp/lines
echo 'filter' >> /tmp/lines
cat /tmp/lines | go run line-filters.go
# HELLO
# FILTER
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"bufio"
"fmt"
"os"
"strings"
)

func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
ucl := strings.ToUpper(scanner.Text())
fmt.Println(ucl)
}

if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
}

Command-Line Arguments

1
2
go build command-line-arguments.go
./command-line-arguments a b c d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"
import "os"

func main() {
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]

arg := os.Args[3]

// [./command-line-arguments a b c d]
fmt.Println(argsWithProg)
// [a b c d]
fmt.Println(argsWithoutProg)
// c
fmt.Println(arg)
}

Command-Line Flags

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"
import "flag"

func main() {
wordPtr := flag.String("word", "foo", "a string")
numPtr := flag.Int("numb", 19, "an int")
boolPtr := flag.Bool("fork", false, "a bool")
var svar string
flag.StringVar(&svar, "svar", "bar", "a string var")

flag.Parse()

fmt.Println("word:", *wordPtr)
fmt.Println("numb:", *numPtr)
fmt.Println("fork:", *boolPtr)
fmt.Println("svar:", svar)
fmt.Println("tail:", flag.Args())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
go build command-line-flags.go

./command-line-flags -word=opt -numb=7 -fork -svar=flag
# word: opt
# numb: 7
# fork: true
# svar: flag
# tail: []

./command-line-flags -word=opt
# word: opt
# numb: 19
# fork: false
# svar: bar
# tail: []

./command-line-flags -word=opt a1 a2 a3
# word: opt
# numb: 19
# fork: false
# svar: bar
# tail: [a1 a2 a3]

./command-line-flags -word=opt a1 a2 a3 -numb=7
# word: opt
# numb: 19
# fork: false
# svar: bar
# tail: [a1 a2 a3 -numb=7]

./command-line-flags -h
# Usage of ./command-line-flags:
# -fork=false: a bool
# -numb=19: an int
# -svar="bar": a string var
# -word="foo": a string

./command-line-flags -wat
# flag provided but not defined: -wat
# Usage of ./command-line-flags:
# -fork=false: a bool
# -numb=19: an int
# -svar="bar": a string var
# -word="foo": a string

Environment Variables

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"
import "os"
import "strings"

func main() {
os.Setenv("FOO", "1")
fmt.Println("FOO:", os.Getenv("FOO"))
fmt.Println("BAR:", os.Getenv("BAR"))

fmt.Println()
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
fmt.Println(pair[0])
}
}
1
2
3
4
5
6
7
8
9
10
11
go run environment-variables.go
# FOO: 1
# BAR:
#
# ...

BAR=2 go run environment-variables.go
# FOO: 1
# BAR: 2
#
# ...

Spawning Processes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import "fmt"
import "io/ioutil"
import "os/exec"

func main() {
dateCmd := exec.Command("date")
dateOut, err := dateCmd.Output()
if err != nil {
panic(err)
}
fmt.Println("> date")
fmt.Println(string(dateOut))

grepCmd := exec.Command("grep", "hello")
grepIn, _ := grepCmd.StdinPipe()
grepOut, _ := grepCmd.StdoutPipe()
grepCmd.Start()
grepIn.Write([]byte("hello grep\ngoodbye grep"))
grepIn.Close()
grepBytes, _ := ioutil.ReadAll(grepOut)
grepCmd.Wait()

fmt.Println("> grep hello")
fmt.Println(string(grepBytes))

lsCmd := exec.Command("bash", "-c", "ls -a -l -h")
lsOut, err := lsCmd.Output()
if err != nil {
panic(err)
}
fmt.Println("> ls -a -l -h")
fmt.Println(string(lsOut))
}

Exec'ing Processes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import "syscall"
import "os"
import "os/exec"

func main() {
binary, lookErr := exec.LookPath("ls")
if lookErr != nil {
panic(lookErr)
}

args := []string{"ls", "-a", "-l", "-h"}
env := os.Environ()
execErr := syscall.Exec(binary, args, env)
if execErr != nil {
panic(execErr)
}
}

Signals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "syscall"
import "os"
import "os/signal"
import "fmt"

func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)

signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()

fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")

// awaiting signal
// ^C
// interrupt
// exiting
}

Exit

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"
import "os"

func main() {
defer fmt.Println("!")
os.Exit(3)
// exit status 3
}