Anda di halaman 1dari 119

Go

Miek Gieben

Go Google

Adam J. GrayAlex SychevAlexey ChernenkovAndrea SpadacciniAndrey Mirtchovski


Anthony MagroBabu SreekanthBen BullockBob CunninghamBrian FallikCecil
NewDamian GryskiDan KortschakDavid OttonFabian BeckerFilip ZaludekHadi
AmiriHaiping FanJaap AkkerhuisJC van WinkelJeroen BultenJinpu HuJohn
ShahidJonathan KansJoshua SteinMakoto InoueMayuresh KathememMichael
StapelbergOlexandr ShalakhinPaulo PintoPeter KleiwegPhilipp SchmidtRobert
JohnsonRussel WinderSonia KeysStefan SchroederThomas KappletT.J. Yang
CoboldSimocUriel :
Alexander Katasonov, Daniele Pala, Iaroslav Tymchenko, Nicolas Kaiser, Marco Ynema.

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.

Miek Gieben 2010 - 2012

2011 - 2013

- - 3.0 Unported http:


//creativecommons.org/licenses/by-nc-sa/3.0/

Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA

Go

Learning as we Go (1.0)
Go 1.1

Contents
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1

iv
1

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Hello World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
arrayslices map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2

26

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
PanicRecover . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3

44

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4

54

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

ii

Chapter: Contents

70

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
6

82

channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7

90

io.Reader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
A

106

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
B

108

C Bibliography

110

List of Exercises
1

(0) For-loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

(0) FizzBuzz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

10

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

11

(1) map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

12

(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

13

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

14

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

15

(0) stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

16

(2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

List of Exercises

17

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

18

(2) interface map . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

19

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

20

(1) Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

21

(1) Cat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

22

(2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

23

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

24

(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

25

(2) max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

26

(1) Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

27

(2) II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

28

(2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

29

(0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

30

(0) Uniq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

31

(2) Quine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

32

(1) Echo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

33

(2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

34

(1) *Finger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

iii


Go
FAQ
GO AUTHORS

Google Go

Go
C[3]C++[21]
Perl[5]Java[15]Erlang[4]Scala[16]Haskell[1]
Go

Qn n
0 2
0.
1.
2.

Q1. (1) map


1 Q1 map()
An n

2
Go

4
Go

5
Go Go

6
go goroutines channel
goroutines

7
Go

Go

http://www.mikespook.com/learning-go/
Michael Davydenko
Miek Gieben2011 miek@miek.nl
2011 mikespook@gmail.com

Go
KEN THOMPSON

Go [13]
Go Go

Go

Go 1 Go Go 1
bug

Source Code Pro


1.

shell %
shell

Go Go Tutorial [12] Effective Go [8] http://golang.


a

org/doc/

Go 1 go doc

% go doc builtin

3
Go

Go
a http://golang.org/doc/

go doc


golang

go

Chapter 1:

Go Go goroutines b
Channel
goroutines channel[18, 25]

Go
Go free()

Go
gofmt

var a int C int a


UTF-8
UTF-8 =
+ 1

Go Go LICENSE

Go
Erlang[4] Go Erlang Go Erlang
Go Erlang Go Go
Unix

Hello World
Go Go Hello World Ken Thompson
Dennis Ritchie 20 70 C
Go Hello World
Listing 1.1. Hello world
package main 0.

import "fmt" 1. // I/O

/* Print something */ 2.

func main() { 3.

coroutines goroutines 6


4.

fmt.Printf("Hello, world ; or

; or

10

")
}

11

0. Go package <something>

package main
1. fmt main main

3 //
2. /* */
3. package main import Go package

import Go
main.main() C
4. 8 fmt "

ASCII

Go go
helloworld
% go build helloworld.go

helloworld
% ./helloworld

Hello, world; or

; or

Go /go $GOROOT GOROOT=/go


Go /g/src $GOPATH GOPATH=/g
3

Go C
(;)

Chapter 1:

Go int a a int
null var a inta
0 var s string s ""
Go
Listing 1.2. =

Listing 1.3. :=

var a i n t

a := 15

var b bool

b := false

a = 15
b = false

var :=

15 int false Go bool


var const import
var (
x int
b bool
)

var x, y int x y int



a, b := 20, 16

a b 20 a16 b
_ 35
b 34
_, b := 34, 35

Go i

package main
func main() {
var i i n t
}

true false bool

Go int 32
32 64 64 int 32 64
uint

int32 uint32
int8int16int32int64 byteuint8uint16uint32
uint64byte uint8 oat32 oat64 float

64 64 32

Listing 1.4.
package main

func main() {

var a i n t

var b int32

32

a = 15

b = a + a

b = b + 5

7
types.go:7: cannot use a + a (type int) as type int32 in assignment

0770xFF1e3 6.022e23

Go constant
const x = 42 x iota c
const (
a = iota
b = iota
)

iota 0 a 0 iota
1 b 1
Go = iota
const (
a = iota
b

Implicitly b

= iota

const (
a = 0

Is an int now

b s t r i n g = "0"
)
c

[iota] not one iota until heaven and


earth pass away, not an iota, not a dot, will pass from the Law.[27]

Chapter 1:

string
s := "Hello World ! "

Go UTF-8
UTF-8 Go string
Go C
Go
var s s t r i n g = "hello"
s[0] = 'c'

Go
s := "hello"
c := [] rune (s)

0.

c[0] = 'c'

1.

s2 := s t r i n g (c)

2.

fmt.Printf("%s\n", s2) 3.
0. s rune 4 59
1.
2. s2
3. fmt.Printf

[8]

s := "Starting part"
+ "Ending part"

s := "Starting part" ;
+ "Ending part" ;

s := "Starting part" +
"Ending part"

Go `

s := `Starting part
Ending part`

rune
Rune int32 UTF-8

US ASCII
Go rune

Go complex128 64
complex64 32 re + imire im

i i ( 1)

Printf() %v

var c complex64 = 5+5i;fmt.Printf("Value is: %v", c)


(5+5i)

Go
error
var e error error e nil error

Go 1.1

Table 1.1.
Precedence

Operator(s)

Highest

| ^

==

!=

<<
<

>>
<=

&
>

&^
>=

<&&

Lowest

||

+ - * / % & | ^ &^

&& ||
!
Go +

Chapter 1:

Go
Table 1.2. Go
break

default

func

interface

select

case

defer

go

map

struct

chan

else

goto

package

switch

const

fallthrough

if

range

type

continue

for

import

return

var

1.2 Go

var const 3
Hello World package import 3

func
return func return 2
go 6
select 6
interface 5
struct 4
type 4

Go d do while for
switch if switch for
select 6 C

if-eles
Go if
{

if x > 0 {
return y
} else {
return x
}
d

[8]

if
return break
if switch

i f err := Chmod(0664) ; err ! = nil {


fmt.Printf(err)

nil C NULL

err if

return err
}
1.1
i f true && true

fmt.Println("true")

}
i f ! false {
fmt.Println("true")

}
Go if
breakcontinuegoto return else
f, err := os.Open(name, os.O_RDONLY, 0)

i f err ! = nil {
return err
}
doSomething(f)

return else

f, err := os.Open(name, os.O_RDONLY, 0)

i f err ! = nil {
return err
}
d, err := f.Stat()

i f err ! = nil {
return err
}
doSomething(f, d)

Go
i f err ! = nil
if

{
return err
}

[8]

10

Chapter 1:

goto
Go goto goto

func myfunc() {
i := 0

Here:

println(i)
i++

goto Here
}

for

Go for
f o r init ; condition ; post { }

C for

f o r condition { }

while

for { }

sum := 0

f o r i := 0 ; i < 10 ; i++ {
sum += i

sum = sum + i

Go ++ for

// Reverse a

f o r i, j := 0, len (a)-1 ; i < j ; i, j = i+1, j-1 {


a[i], a[j] = a[j], a[i]

}
break continue
break break
f o r i := 0 ; i < 10 ; i++ {
if i > 5 {
break

0 5

}
println(i)

}
break

f o r j := 0 ; j < 5 ; j++ {

J:

f o r i := 0 ; i < 10 ; i++ {
if i > 5 {
break J

j i

}
println(i)

}
}
continue 0
5
f o r i := 0 ; i < 10 ; i++ {
if i > 5 {
continue

println(i)

range
range slicearraystringmap channel 6
range
range
slice array range

list := [] s t r i n g { "a", "b", "c", "d", "e", "f" }

f o r k, v := range list {

0.

1.

// k v 2.

}
0. slice arrayslices map 14
1. range range int string

0 a
2. k 05 v af

range Unicode e
UTF-8
f o r pos, char := range "ax" {
fmt.Printf("character '%c' starts at byte position %d\n", char
, pos)

UTF-8 runes 8 UTF-8


32 runechar rune

11

12

Chapter 1:

character 'a' starts at byte position 0


character '' starts at byte position 1
character 'x' starts at byte position 3

took 2 bytes

switch
Go switch
switch true switch
if-else-if-else
func unhex(c byte ) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
fallthrough
fallthrough
switch i {
case 0:

// case

case 1:
f()

// i == 0 f

switch i {
case 0:

fallthrough

case 1:
f()

// i == 0 f

}
default
switch i {
case 0:
case 1:
f()

default :
g()

// i 0 1

func shouldEscape(c byte ) bool {


switch c {
case ' ', '?', '&', '=', '#', '+':

, as or

return true
}
return false
}
switch
0.

func Compare(a, b [] byte ) i n t {


f o r i := 0 ; i < len (a) && i < len (b) ; i++ {
switch {
case a[i] > b[i]:
return 1
case a[i] < b[i]:
return -1
}
}
switch { 1.
case len (a) < len (b):
return -1
case len (a) > len (b):
return 1
}
return 0

2.

}
0.

a == b 0 a < b -1 a > b +1
1.
2.

1.3
f
Table 1.3. Go
close

new

panic

complex

delete

make

recover

real

len

append

print

imag

cap

copy

println

f go doc builtin

13

14

Chapter 1:

Go builtin
close

channel channel 6
delete

map
len cap

len slice arrayslices


map slice cap
new

new 55
make

mapslice channel make


55
copy

slice slice
append

slice slice
panic recover

PanicRecover 32

print println

fmt
complexreal imag

arrayslices map
array slice
Go map
array
array [n]<type> n array <type>
array
var arr [10] i n t
arr[0] = 42
arr[1] = 13
fmt.Printf("The first element is %d\n", arr[0])

var arr = [10]int

arrayslices map

15

var a [3]int
a := [3]int{1, 2, 3} a := [...]int{1, 2, 3}Go

array slice

a := [3][2] i n t { [2] i n t { 1,2 } , [2] i n t { 3,4 } , [2] i n t { 5,6 } }

56

map

a := [3][2] i n t { [...] i n t { 1,2 } , [...] i n t { 3,4 } , [...] i n t { 5,6 } }

array (...)

arrayslice map arrayslice

map

a := [3][2] i n t { { 1,2 } , { 3,4 } , { 5,6 } }

slice
slice array slice
arrayslice array array slice
slice array

slice slice

make

array
sl := make([] int , 10)

10 slice array slice


array slice 1.1
Go m array intvar array[m]int
array sliceslice := array[0:n]

16

Chapter 1:

Figure 1.1. array slice


len(slice)== n ; cap(slice)== m ; len(array)== cap(array)== m .
0

n-1

...

m-1

array

len == cap == m

n-1

...

len == n

m-1

slice

cap == m

array slice slice a[I:J]


slice a I J J - I
// array[n:m] array slice n m-1
a := [...] i n t { 1, 2, 3, 4, 5 } 0.
s1 := a[2:4] 1.

arrayslices map
s2 := a[1:5] 2.
s3 := a[:]

3.

s4 := a[:4]

4.

s5 := s2[:]

5.

0. 5 array 0 4
1. 2 3 slice 3, 4
2. 1 4 2, 3, 4, 5
3. array slice a[0:len(a)]
4. 0 3 a[0:4] 1, 2, 3, 4
5. slice s2 slice s5 array a

1.5
array
Listing 1.5. array slice
package main

func main() {

var array [100] i n t

Create array, index from 0 to 99

slice := array[0:99]

Create slice, index from 0 to 98

slice[98] = 'a'

OK

slice[99] = 'a'

Error:

throw: index out of range

8
9

sliceappend copy
[10]

append slice s x s
slice s append
slice slice
slice array
s0 := [] i n t { 0, 0 }
s1 := append(s0, 2) 0.
s2 := append(s1, 3, 5, 7) 1.
s3 := append(s2, s0...) 2.

0. s1 == []int{0, 0, 2}
1. s2 == []int{0, 0, 2, 3, 5, 7}
2. slices3 == []int{0, 0, 2, 3, 5, 7, 0, 0}

17

18

Chapter 1:

copy slice src dst

len(src) len(dst)

var a = [...] i n t { 0, 1, 2, 3, 4, 5, 6, 7 }
var s = make([] int , 6)
n1 := copy (s, a[0:])

n1

== 6, s == []int{0, 1, 2, 3, 4, 5}

n2 := copy (s, s[2:])

n2

== 4, s == []int{2, 3, 4, 5, 4, 5}

map
Perl Python C++
map Go map map
map string
int map map[<from type>]<to type>
monthdays := map[ s t r i n g ] i n t {
"Jan": 31, "Feb": 28, "Mar": 31,
"Apr": 30, "May": 31, "Jun": 30,
"Jul": 31, "Aug": 31, "Sep": 30,
"Oct": 31, "Nov": 30, "Dec": 31,

}
map make monthdays := make(map
[string]int)

map 12 fmt.Printf("
%d\n", monthdays["Dec"])

arrayslicestring map range

year := 0

_,

f o r _, days := range monthdays {

days

year += days

}
fmt.Printf("Numbers of days in a year: %d\n", year)

map
monthdays["Undecim"] = 30

monthdays["Feb"]

= 29

[19]
var value i n t
var present bool
value, present = monthdays["Jan"]

present true

Go
v, ok := monthdays["Jan"]

ok

map
Mar

delete(monthdays, "Mar")

delete(m, x) map m[x]

Q1. (0) For-loop


1. for 10 fmt

2. goto 1 for
3. array array
Q2. (0) FizzBuzz
1. Fizz-Buzz[23]

1 100

Fizz

Buzz

FizzBuzz
Q3. (1)
1. Go 100
A
AA
AAA
AAAA
AAAAA
AAAAAA
AAAAAAA
...

2.
asSASA ddd dsjkdsjs dk

unicode/utf8
3. / 4 abc
4. Go foobar raboof
59
Q4. (1)
1. float64 slice Q5

19

A1. (0) For-loop


1.
Listing 1.6.
package main
import "fmt"
func main() {
f o r i := 0 ; i < 10 ; i++ {

See page 10

fmt.Printf("%d\n", i)

}
}

% go build for.go
% ./for
0
1
.
.
.
9

2. main
func main() {
i := 0

Loop:

fmt.Printf("%d\n", i)

i f i < 10 {
i++

goto Loop
}
}
3.

Listing 1.7. for


func main() {
var arr [10] i n t

Create an array with 10 elements

f o r i := 0 ; i < 10 ; i++ {
arr[i] = i

Fill it one by one

}
fmt.Printf("%v", arr)

With %v Go prints the value for us

21

22

Chapter 1:

a := [...] i n t { 0,1,2,3,4,5,6,7,8,9 }

Go

fmt.Printf("%v\n", a)

A2. (0) FizzBuzz


1.
Listing 1.8. Fizz-Buzz
package main
import "fmt"
func main() {
const (
FIZZ = 3 0.
BUZZ = 5
)

var p bool

1.

f o r i := 1 ; i < 100 ; i++ { 2.


p = false

i f i%FIZZ == 0 { 3.
fmt.Printf("Fizz")
p = true

}
i f i%BUZZ == 0 { 4.
fmt.Printf("Buzz")
p = true

}
i f ! p { 5.
fmt.Printf("%v", i)

}
fmt.Println() 6.

}
}
0.
1.
2. for for
3. FIZZ Fizz
4. BUZZ BuzzFizzBuzz
5. FIZZ BUZZ
6.

A3. (1)

1.

Listing 1.9.
package main
import "fmt"
func main() {
str := "A"

f o r i := 0 ; i < 100 ; i++ {


fmt.Printf("%s\n", str)
str = str + "A"

String concatenation

}
}

2. unicode/utf8 go doc
unicode/utf8 | less func RuneCount(p []

byte)int string byte slice

str := "hello"
b

:= [] byte (str)

59

Listing 1.10. rune


package main
import (
"fmt"
"unicode/utf8"
)

func main() {
str := "dsjkdshdjsdh....js"
fmt.Printf("String %s\nLength: %d, Runes: %d\n", str,

len ([] byte (str)), utf8.RuneCount([] byte (str)))


}

23

24

Chapter 1:

package main
import (
"fmt"
)

3. func main() {
s := "

"

r := [] rune (s)

copy (r[4:4+3], [] rune ("abc"))


fmt.Printf("Before: %s\n", s) ;
fmt.Printf("After : %s\n", s t r i n g (r))

}
4. ij

Listing 1.11. Reverse a string


import "fmt"
func main() {
s := "foobar"

Again a conversion

a := [] rune (s)

f o r i, j := 0, len (a)-1 ; i < j ; i, j = i+1, j-1 {


a[i], a[j] = a[j], a[i]

Parallel assignment

}
fmt.Printf("%s\n", s t r i n g (a))

Convert it back

A4. (1)
1.
sum := 0.0

switch len (xs) {


0.

case 0:
avg = 0

1.

default :

f o r _, v := range xs {
sum += v

}
avg = sum / float64 ( len (xs)) 2.

}
0. 0
1.


2. float64

25

RICHARD P. GABRIEL

Go

Listing 2.1.
.
type mytype i n t

func
funcname(q
i .n t ) (r,s . i n t ) { return. 0,0 }
. (p mytype)
.
.
0

0. func
1. method

5
2. funcname
3. int q pass-by-value

4. r s Go

28 (int,int)

5. return

func subroutine(in i n t ) { return }


func identity(in i n t ) i n t { return in }
Go
Go
31

Listing 2.2.
func rec(i i n t ) {
i f i == 10 {
return
}
rec(i+1)
fmt.Printf("%d ", i)

}
9 8 7 6 5 4 3 2 1 0

Go

Listing 2.3.

Listing 2.4.

package main

package main

var a = 6

var a = 6

func main() {

func main() {

p()

p()

q()

q()

p()

p()

func p() {

func p() {

println(a)

println(a)

func q() {

func q() {

a := 5

a = 5

println(a)

println(a)

2.3 q() a a q()


656 2.4 a a
655
f() g()
Listing 2.5.
package main

27

28

Chapter 2:

var a i n t
func main() {
a = 5
println(a)
f()

}
func f() {
a := 6
println(a)
g()

}
func g() {
println(a)

}
565

Go Python
Perl C
EOF -1 Go Write

os *File.Write
func (file *File) Write(b [] byte ) (n int , err e r r o r )
n != len(b) nil error
Go

Go

return
a
int
nextPos
func nextInt(b [] byte , pos i n t ) (value, nextPos i n t ) { /* ... */ }
a

Go

return
io.ReadFull
func ReadFull(r Reader, buf [] byte ) (n int , err e r r o r ) {
f o r len (buf) > 0 && err == nil {
var nr i n t
nr, err = r.Read(buf)
n += nr
buf = buf[nr: len (buf)]

}
return
}

Listing 2.6. defer


func ReadWrite() bool {
file.Open("file")
//

i f failureX {

file.Close()

return false
}
i f failureY {

file.Close()

return false
}
file.Close()

return true
}
Go defer defer

Close Open

Listing 2.7. defer


func ReadWrite() bool {
file.Open("file")

defer file.Close()
//

i f failureX {

file.Close() defer

29

30

Chapter 2:

Close()

return false
}
i f failureY {

return false
}

And here

return true
}

[8]
f o r i := 0 ; i < 5 ; i++ {
defer fmt.Printf("%d ", i)
}
LIFO4 3 2 1 0
defer b
Listing 2.8.
defer func () {
/* ... */

()

} ()

Listing 2.9.
defer func (x i n t ) {
/* ... */

} (5)

x 5

Listing 2.10. defer


func f() (ret i n t ) {

ret

defer func () {
ret++

ret 1

} ()
return 0

1 0

func myfunc(arg ... i n t ) { }


arg ...int Go int

arg int slice


b

f o r _, n := range arg {
fmt.Printf("And the number is: %d\n", n)

}
interface{} 5
myfunc2
func myfunc(arg ... i n t ) {

myfunc2(arg...)

myfunc2(arg[:2]...)

Go

Listing 2.11.
func main() {
a

a := func () {
println("Hello")

()

a()

}
fmt.Printf("\%T\n", a) a func()
map
Listing 2.12. map
var xs = map[ i n t ] func () i n t {
1: func () i n t { return 10 } ,
2: func () i n t { return 20 } ,
3: func () i n t { return 30 } ,

/* ... */

}
int slice Map
34 Q11


func printit(x i n t ) {

fmt.Printf("%v\n", x)

31

32

Chapter 2:

func printit(int)func(int)

func callback(y int , f func ( i n t )) {

f y

f(y)

PanicRecover
Go Java Java
panic-and-recover

[7]
Panic

F panic F F
F F panic
goroutine
panic

Recover
goroutine recover

recover nil
goroutine recover panic

panic c
func throwsPanic(f func ()) (b bool ) { 0.
defer func () { 1.
i f x := recover() ; x ! = nil {
b = true

}
} ()
f() 2.

return 3.
}

0. throwsPanic

f panic true false


c

Eleanor McHugh


1. recover defer goroutine panic

defer recover() nil b true


2.
3. b b

28 b

Q5. (0)
1. float64 slice
Q6. (0)
1.
f(7,2) 2,7
f(2,7) 2,7

Q7. (1)
1.
package main

import "fmt"

func main() {

f o r i := 0 ; i < 10 ; i++ {

fmt.Printf("%v\n", i)

fmt.Printf("%v\n", i)

10

Q8. (1)
1. push
pop LIFO

Figure 2.1. LIFO


i++

k
l

push(k)

pop()

i--

33

34

Chapter 2:

2. String
fmt.Printf("My stack %v\n", stack)
[0:m] [1:l] [2:k]
Q9. (1)
1.
Q10. (1)
1. 1, 1, 2, 3, 5, 8, 13, . . . x1 = 1; x2 =
1; xn = xn1 + xn2

n > 2

int
Q11. (1) map

map()

map(f (), (a1 , a2 , . . . , an1 , an )) = (f (a1 ), f (a2 ), . . . , f (an1 ), f (an ))

1. Go map()
2.
Q12. (0)
1. int slice ([]int)
2. int slice ([]int)
Q13. (1)
1. int slice [24]



[24]
procedure bubbleSort( A : list of sortable items )
do
swapped = f a l s e

f o r each i in 1 to length(A) - 1 inclusive do:


i f A[i-1] > A[i] then
swap( A[i-1], A[i] )
swapped = true

end i f
end f o r
while swapped
end procedure

Q14. (1)
1. +2
plusTwo
p := plusTwo()
fmt.Printf("%v\n", p(2))

4 31
2. 1 plusX(x)
x

35

A5. (0)
1.
Listing 2.13. Go
func average(xs [] float64 ) (avg float64 ) { 0.
sum := 0.0

switch len (xs) {


1.

case 0:
avg = 0

2.

default :

f o r _, v := range xs {
sum += v

}
avg = sum / float64 ( len (xs)) 3.

}
return

4.

}
0.
1. 0
2.
3. float64
4.

A6. (0)
1. Go
func order(a, b i n t ) ( int , i n t ) {
if a > b {
return b,a
}
return a,b
}

A7. (1)
1. 9 ii for
main()
func main() {
var i i n t
f o r i = 0 ; i < 10 ; i++ {
fmt.Printf("%v\n", i)

37

38

Chapter 2:

}
fmt.Printf("%v\n", i)

}
i for 0 10
A8. (1)
1.
10
type stack s t r u c t {

int

data [10] i n t

}
push pop Go
push

func (s stack) push(k i n t ) {

i f s.i+1 > 9 {
return
}
s.data[s.i] = k
s.i++

}
stack s s.push(50)
50 push s

var s stack

s stack

s.push(25)
fmt.Printf("stack %v\n", s) ;
s.push(14)
fmt.Printf("stack %v\n", s) ;

stack [0:0]
stack [0:0]

push
push
func (s stack)push(k int) func (s *stack)push(k int)
new() 4 new stack
1 s := new(stack)

func (s *stack) push(k i n t ) {


s.data[s.i] = k
s.i++

}
func (s *stack) pop() i n t {
s.i--

return s.data[s.i]
}

func main() {
var s stack
s.push(25)
s.push(14)
fmt.Printf("stack %v\n", s)

}
2.
Go fmt.Printf("\%v") Stringer
%v String()
Listing 2.14. stack.String()
func (s stack) String() s t r i n g {
var str s t r i n g
f o r i := 0 ; i <= s.i ; i++ {
str = str + "[" +
strconv.Itoa(i) + ":" + strconv.Itoa
(s.data[i]) + "]"

}
return str
}

A9. (1)
1. ...
Listing 2.15.
package main
import "fmt"
func main() {
prtthem(1, 4, 5, 7, 4)
prtthem(1, 2, 4)

39

40

Chapter 2:

func prtthem(numbers ... i n t ) {

numbers slice

f o r _, d := range numbers {
fmt.Printf("%d\n", d)

}
}

A10. (1)
1.
Listing 2.16. Go
package main
import "fmt"
func fibonacci(value i n t ) [] i n t {
x := make([] int , value) 0.
x[0], x[1] = 1, 1 1.

f o r n := 2 ; n < value ; n++ {


x[n] = x[n-1] + x[n-2] 2.

}
return x 3.
}
func main() {
f o r _, term := range fibonacci(10) { 4.
fmt.Printf("%v ", term)

}
}
0. array
1.
2. xn = xn1 + xn2 ;
3. array
4. range

10
A11. (1) map
Listing 2.17. Map
1. func Map(f func ( i n t ) int , l [] i n t ) [] i n t {
j := make([] int , len (l))

f o r k, v := range l {
j[k] = f(v)

return j
}
func main() {
m := [] i n t { 1, 3, 4 }
f := func (i i n t ) i n t {

return i * i
}
fmt.Printf("%v", (Map(f, m)))

}
2.
A12. (0)
1. slice l
func max(l [] i n t ) (max i n t ) {

0.

max = l[0]

f o r _, v := range l {
i f v > max {

1.
2.

max = v

}
}
return

3.

}
0.
1. l
2.
3. max

2. slice l max
func min(l [] i n t ) (min i n t ) {
min = l[0]

f o r _, v := range l {
i f v < min {
min = v

}
}
return
}
max min

A13. (1)

41

42

Chapter 2:

1. n O(n2 )
[17]

Listing 2.18.
func main() {
n := [] i n t { 5, -1, 0, 12, 3, 5 }
fmt.Printf("unsorted %v\n", n)
bubblesort(n)
fmt.Printf("sorted %v\n", n)

}
func bubblesort(n [] i n t ) {
f o r i := 0 ; i < len (n) - 1 ; i++ {
f o r j := i + 1 ; j < len (n) ; j++ {
i f n[j] < n[i] {
n[i], n[j] = n[j], n[i]

}
}
}
}
slice bubblesort
slice
A14. (1)
1. func main() {
p2 := plusTwo()
fmt.Printf("%v\n",p2(2))

}
func plusTwo() func ( i n t ) i n t { 0.
return func (x i n t ) i n t { return x + 2 } 1.
}
0.
1. +2

2.
func plusX(x i n t ) func ( i n t ) i n t { 0.
return func (y i n t ) i n t { return x + y } 1.
}
0.
1. x

KEN THOMPSON

package
Go
package <name> even.go even
Listing 3.1.
package even

func Even(i i n t ) bool {

return i % 2 == 0
}

func odd(i i n t ) bool {


return i % 2 == 1
}

$GOPATH even.go
1
% mkdir $GOPATH/src/even
% cp even.go $GOPATH/src/even
% go build
% go install

myeven.go
Listing 3.2. even
package main
import ( 0.
"even"

1.

"fmt"

2.

func main() {
i := 5
fmt.Printf("Is %d even? %v\n", i, even.Even(i)) 3.


0.
1. even
2. fmt
3. even <package>.Function()
% go build myeven.go
% ./myeven
Is 5 even? false

Go
Even myeven.go 10
even.odd
fmt.Printf("Is %d even? %v\n", i, even.odd(i))

myeven.go:10: cannot refer to unexported name even.odd




US ASCII

Go

Go
Atoi
GetwdChmod

ReadFileNewWriterMakeSlice

import
import "bytes"
bytes.Buffer

45

46

Chapter 3:

import bar "bytes"


Buffer bar.Buffer

src/pkg/compress/gzip compress/gzip
gzip compress_gzip compressGzip

buo Reader BufReader


bufio.Reader
bufio.Reader io.Reader ring.Ring
container/ring Go NewRing
Ring ring
New ring.New
once.Do synconce.Do(setup)
once.DoOrWaitUntilDone(setup)

Go MixedCaps mixedCaps

[8]

package

go doc
regexp
/*
The regexp package implements a simple library for
regular expressions.

The syntax of the regular expressions accepted is:

regexp:
concatenation

'|' concatenation

*/
package regexp

fmt

// Printf formats according to a format specifier and writes to standard


// output. It returns the number of bytes written and any write error
// encountered.
func Printf(format string, a ...interface) (n int, err error)

Go testing go
test
go test even go test

% go test
?

even

[no test files]


*_test.go Go go test

Test
func TestXxx(t *testing.T)
go test
[11] go doc testing go
help testfunc

func (t *T) Fail()


Fail

func (t *T) FailNow()


FailNow

func (t *T) Log(args ... i n t e r f a c e { } )


Log Print()

func (t *T) Fatal(args ... i n t e r f a c e { } )


Fatal Log() FailNow()

even_test.go

Listing 3.3. even


package even

import "testing"

func TestEven(t *testing.T) {

i f ! Even(2) {

}
}

t.Log("2 should be even ! ")

t.Fail()

8
9
10

47

48

Chapter 3:

package even
testing
5 Go
Even
% go test
ok

even

0.001s

ok

// Entering the twilight zone

func TestEven(t *testing.T) {


i f Even(2) {
t.Log("2 should be odd ! ")
t.Fail()

}
}

FAIL

even

0.004s

--- FAIL: TestEven (0.00 seconds)


2 should be odd!
FAIL

The Go test suite also allows you to incorperate example functions which serve as documentation and as tests. These functions need to start with Example.
func ExampleEven() {
i f Even(2) {
fmt.Printf("Is even\n")

}
// Output:
// Is even

}
Those last two comments lines are part of the example, go test uses those to check the
generated output with the text in the comments. If there is a mismatch the test fails.

Go Go
$GOROOT/src/pkg
a
a go doc

fmt
fmt I/O C printf scanf
C %-
%v
%+v
%#v
Go
%T
Go
io
I/O os I/O

buo
I/O io.Reader io.Writer
Reader Writer I/O
sort
sort
strconv
strconv

os
os Unix
sync
sync
ag
ag 92
encoding/json
encoding/json RFC 4627 [2] JSON
html/template
HTML

map
@
net/http
net/http HTTP URL HTTP
HTTP
unsafe
unsafe Go

49

50

Chapter 3:

reect
reect
interface{} Typeof
Type

5
os/exec
os/exec

Q15. (0) stack


1. Q8 stack
PushPop Stack
2. Push Pop
Q16. (2)
1. stack

A15. (0) stack


1. stack
Stack stack-as-package.go

Listing 3.4. Stack


package stack
// Stack

type Stack s t r u c t {
i

int

data [10] i n t

}
// Push

func (s *Stack) Push(k i n t ) {


s.data[s.i] = k
s.i++

}
// Pop

func (s *Stack) Pop() (ret i n t ) {


s.i-ret = s.data[s.i]

return
}
2.
pushpop_test.go
Listing 3.5. Push/Pop
package stack
import "testing"
func TestPushPop(t *testing.T) {
c := new(Stack)
c.Push(5)

i f c.Pop() ! = 5 {
t.Log("Pop doesn't give 5")
t.Fail()

}
}

51

52

Chapter 3:

go test $GOPATH/src
% mkdir $GOPATH/src/stack
% cp pushpop_test.go $GOPATH/src/stack
% cp stack-as-package.go $GOPATH/src/stack

% go test stack
ok

stack

0.001s

A16. (2)
1.
Listing 3.6.
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)

var reader *bufio.Reader = bufio.NewReader(os.Stdin)


var st = new(Stack)
type Stack s t r u c t {
i

int

data [10] i n t

}
func (s *Stack) push(k i n t ) {
i f s.i+1 > 9 {
return
}
s.data[s.i] = k
s.i++

}
func (s *Stack) pop() (ret i n t ) {
s.i--

i f s.i < 0 {
s.i = 0

return
}
ret = s.data[s.i]

return

}
func main() {
for {
s, err := reader.ReadString('\n')

var token s t r i n g
i f err ! = nil {
return
}
f o r _, c := range s {
switch {
case c >= '0' && c <= '9':
token = token + s t r i n g (c)

case c == ' ':


r, _ := strconv.Atoi(token)
st.push(r)
token = ""

case c == '+':
fmt.Printf("%d\n", st.pop()+
st.pop())

case c == '*':
fmt.Printf("%d\n", st.pop()*
st.pop())

case c == '-':
p := st.pop()
q := st.pop()
fmt.Printf("%d\n", q-p)

case c == 'q':
return
default :
//error

}
}
}
}

53

Go

Go For C++ Programmers


GO AUTHORS

Go C
Go

*var p *int p

nilNULL Go
nil &
Listing 4.1.
var p * i n t
fmt.Printf("%v", p)

nil

var i i n t

p = &i

p i

fmt.Printf("%v", p)

0x7ff96b81c000a

*
Listing 4.2.
p = &i

*p = 8

fmt.Printf("%v\n", *p)

fmt.Printf("%v\n", i)

*p++ (*p)++
a

Go
Go new make
Go
new make
a

17

new
new new(T)
T *T Go
T
new
bytes.Buffer Buffer
sync.Mutex Init sync.Mutex

57
type SyncedBuffer s t r u c t {
lock

sync.Mutex

buffer

bytes.Buffer

}
SyncedBuffer p v

p := new(SyncedBuffer)

Type *SyncedBuer

var v SyncedBuffer

Type SyncedBuer

make
make(T, args) new(T)
slicemap channel T *T

slice array
slice nil slicemap channelmake

make([]int, 10, 100) 100 10 100


slice 10 new([]int)
slice nil slice
new make
var p *[] i n t = new([] i n t )

slice

var v

v 100

[] i n t = make([] int , 100)

var p *[] i n t = new([] i n t )

*p = make([] int , 100, 100)


v := make([] int , 100)

make mapslice channel new

55

56

Chapter 4:

new make

new(T) *T T
make(T) T
make slicemap channel

os

func NewFile(fd int , name s t r i n g ) *File {


i f fd < 0 {
return nil
}
f := new(File)
f.fd = fd
f.name = name
f.dirinfo = nil
f.nepipe = 0

return f
}

func NewFile(fd int , name s t r i n g ) *File {


i f fd < 0 {
return nil
}
f := File { fd, name, nil, 0 }

return &f

Create a new File

b
return &File { fd, name, nil, 0 }
The items (called of a composite +literal are laid out in order and must all be
:

return &File { fd: fd, name: name }


b

new(File) &File{}
arrayslice map map
EnoneEio Einval

ar := [...] s t r i n g { Enone: "no error", Einval: "invalid argument" }


sl := [] s t r i n g { Enone: "no error", Einval: "invalid argument" }
ma := map[ i n t ] s t r i n g { Enone: "no error", Einval: "invalid argument
"}

Go type
type foo i n t
foo int struct
stringint

Listing 4.3.
package main
import "fmt"
type NameAge s t r u c t {
name s t r i n g
age

int

}
func main() {
a := new(NameAge)
a.name = "Pete" ; a.age = 42
fmt.Printf("%v\n", a)

}
fmt.Printf("%v\n", a)
&{Pete 42}

Go
.<field name>
fmt.Printf("%s", a.name)

%s

57

58

Chapter 4:

eldstruct {}
c
struct {
x, y i n t
A *[] i n t
F func ()

struct {
T1

T1

*T2

T2

P.T3

T3

x, y i n t

x y

1.
func doSomething(n1 *NameAge, n2 i n t ) { /* */ }

2. 2.1
func (n1 *NameAge) doSomething(n2 i n t ) { /* */ }

var n *NameAge
n.doSomething(2)

[10]

x &x mx.m() (&x).m()

c 4

var n NameAge
n.doSomething(2)

Go NameAge n *NameAge
(&n).doSomething(2)
[10, section Type
Declarations]
// Mutex Lock Unlock

type Mutex s t r u c t

{ /* Mutex */ }

func (m *Mutex) Lock()

{ /* Lock */ }

func (m *Mutex) Unlock()

{ /* Unlock */ }

type NewMutex Mutex;


type PrintableMutex struct {Mutex }.
NewMutux Mutex Mutex

PrintableMutex Mutex [10]


*PrintableMutex Lock Unlock

Mutex

Go
byte()

Table 4.1. oat64 oat32 oat32

t32
From

b []byte

i []int

r []rune

s string

f flt32

i int

To
[]byte

[]byte(s)

[]int
[]rune
string

string(b)

string(i)

[]int(s)

[]rune(s)

string(r)

ftl32

flt32(i)

int

int(f)

string ruin slice


mystring := "hello this is string"

59

60

Chapter 4:

byteslice := [] byte (mystring)

byte slice byte Go


UTF-8 123 4
runeslice

:= [] rune (mystring)

rune slice rune Unicode

slice string
b := [] byte { 'h','e','l','l','o' } //
s := s t r i n g (b)
i := [] rune { 257,1024,65 }
r := s t r i n g (i)

bituint8(int)
int (oat32)
oat32(int)

Foo Bar Bar Foo

type foo s t r u c t { i n t }

type bar foo

bar foo

var b bar = bar { 1 }

b bar

var f foo = b

b f

cannot use b (type bar) as type foo in assignment( b bar

foo )

var f foo = foo(b)


b int

TODO(miek):work in progress Go
Go

Q17. (1)
1. 54
*p++ (*p)++

2.
Q18. (2) interface map
1. Q11 interface
int string
Q19. (1)
1.
type Person s t r u c t {
name s t r i n g
age

int

var p1 Person
p2 := new(Person)

2.
func Set(t *T) {
x = t

func Set(t T) {
x= &t

Q20. (1) Linked List


1. Make use of the package container/list to create a (doubly) linked list. Push the
values 1, 2 and 4 to the list and then print it.
2. Create your own linked list implementation. And perform the same actions as in
question 1
Q21. (1) Cat

61

62

Chapter 4:

1. Unix cat
blah
% cat blah

2. n
3. 1 Bug
Q22. (2)
1. container/vector Go
append
push pop
package main
import "container/vector"
func main() {
k1 := vector.IntVector { }
k2 := &vector.IntVector { }
k3 := new(vector.IntVector)
k1.Push(2)
k2.Push(3)
k3.Push(4)

}
k1k2 k3

2. Push
Push
func (p *IntVector) Push(x int) Push x
*IntVector Push
above (the Push statements) work correct then?

A17. (1)
1. int, uint
2. ++ Go

A18. (2) interface map


Listing 4.4. Go map
1. package main
import "fmt"
//* define the empty interface as a type

type e i n t e r f a c e { }
func mult2(f e) e {
switch f.( type ) {
case i n t :
return f.( i n t ) * 2
case s t r i n g :
return f.( s t r i n g ) + f.( s t r i n g ) + f.( s t r i n g )
+ f.( s t r i n g )

}
return f
}
func Map(n []e, f func (e) e) []e {
m := make([]e, len (n))

f o r k, v := range n {
m[k] = f(v)

}
return m
}
func main() {
m := []e { 1, 2, 3, 4 }
s := []e { "a", "b", "c", "d" }
mf := Map(m, mult2)
sf := Map(s, mult2)
fmt.Printf("%v\n", mf)
fmt.Printf("%v\n", sf)

63

64

Chapter 4:

A19. (1)
1. var p1 Person Person- p1p1 Person
p2 := new(Person) p2p2
*Person

2. x t

x t

A20. (1) Linked List
1. The following is the implementation of a program using doubly linked lists from
container/list.
Listing 4.5. Doubly linked list using container/list
package main
import (
"fmt"
"container/list"
)

func main() {
l := list.New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(4)

f o r e := l.Front() ; e ! = nil ; e = e.Next() {


fmt.Printf("%v\n", e.Value)

}
}
2. The following is a program implementing a simple doubly linked list supporting
int values.

Listing 4.6. Doubly linked list


package main
0.

import (
"errors"
"fmt"
)

type Value i n t 1.

type Node s t r u c t { 2.
Value
prev, next *Node

}
type List s t r u c t {
head, tail *Node

}
3.

func (l *List) Front() *Node {


return l.head
}
func (n *Node) Next() *Node {
return n.next
}
func (l *List) Push(v Value) *List {
n := &Node { Value: v } 4.
i f l.head == nil { 5.
l.head = n

} else {
l.tail.next = n 6.
n.prev = l.tail 7.

}
l.tail = n 8.

return l
}
var errEmpty = errors.New("List is empty")
func (l *List) Pop() (v Value, err e r r o r ) {
i f l.tail == nil { 9.
err = errEmpty

} else {
.
v = l.tail.Value 10
.
l.tail = l.tail.prev 11
i f l.tail == nil {
.
l.head = nil 12
}
}

65

66

Chapter 4:

return v, err
}
func main() {
l := new(List)
l.Push(1)
l.Push(2)
l.Push(4)

f o r n := l.Front() ; n ! = nil ; n = n.Next() {


fmt.Printf("%v\n", n.Value)

}
fmt.Println()

f o r v, err := l.Pop() ; err == nil ; v, err = l.Pop()


{
fmt.Printf("%v\n", v)

}
}
0. Include all the packages we need.
1. Declare a type for the value our list will contain;
2. declare a type for the each node in our list;
3. Mimic the interface of container/list.
4. When pushing, create a new Node with the provided value;
5. if the list is empty, put the new node at the head;
6. otherwise put it at the tail;
7. make sure the new node points back to the previously existing one;
8. point tail to the newly inserted node.
9. When popping, return an error if the list is empty;

.
10
otherwise save the last value;
.
11
discard the last node from the list;
.
12
and make sure the list is consistent if it becomes empty;
A21. (1) Cat
1. cat n
Listing 4.7. cat
package main


0.

import (
"io"
"os"
"fmt"
"bufio"
"flag"
)

var numberFlag = flag.Bool("n", false, "number each line") 1.


2.

func cat(r *bufio.Reader) {


i := 1

for {
buf, e := r.ReadBytes('\n')

3.

i f e == io.EOF {

4.

break
}
5.

i f *numberFlag {

fmt.Fprintf(os.Stdout, "%5d

%s", i,

buf)
i++
6.

} else {

fmt.Fprintf(os.Stdout, "%s", buf)

}
}
return
}
func main() {
flag.Parse()

i f flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin))

}
f o r i := 0 ; i < flag.NArg() ; i++ {
f, e := os.Open(flag.Arg(i))

i f e ! = nil {
fmt.Fprintf(os.Stderr, "%s: error
reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.
Error())

continue
}
cat(bufio.NewReader(f))

67

68

Chapter 4:

}
}
0.
1. n
2.
3.
4.
5.
6.

2. Bug

Listing 4.8. cat


package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
)

var numberFlag = flag.Bool("n", false, "number each line")


func cat(r *bufio.Reader) {
i := 1

for {
buf, e := r.ReadBytes('\n')

i f e == io.EOF {
break
}
i f *numberFlag {
fmt.Fprintf(os.Stdout, "%5d

%s", i,

buf)
i++

} else {
fmt.Fprintf(os.Stdout, "%s", buf)

}
}
return
}

func main() {
flag.Parse()

i f flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin))

}
f o r i := 0 ; i < flag.NArg() ; i++ {
f, e := os.Open(flag.Arg(i))

i f e ! = nil {
fmt.Fprintf(os.Stderr, "%s: error
reading from %s: %s\n",
os.Args[0], flag.Arg(i), e.
Error())

continue
}
cat(bufio.NewReader(f))

}
}

A22. (2)
1. k1 vector.IntVector {}
k2 *vector.IntVector&
k3 *vector.IntVector new
2. [10]

x m m
x.m() x &x m
x.m() (&x).m()

k1 *vector.IntVector Push
k1.Push(2) Go (&k1).Push(2)
d

69

eXistenZ
TED PIKUL

[22] Ian Lance

Go interface
S

Taylor

Listing 5.1.

Go

type S s t r u c t { i i n t }
func (p *S) Get() i n t { return p.i }
func (p *S) Put(v i n t ) { p.i = v }
I
type I i n t e r f a c e {
Get() i n t
Put( i n t )

}
IS I
S I
Go :
func f(p I) {

0.

fmt.Println(p.Get()) 1.
p.Put(1) 2.

}
0.
1. p I Get()
2. Put()

p S I f S

var s S ; f(&s)
s S s
5.1 Put

Go duck typing[26]
duck typing Go

Go

Go C++ Haskell
typeclasses Python duck typing

Go

I
type R s t r u c t { i i n t }
func (p *R) Get() i n t { return p.i }
func (p *R) Put(v i n t ) { p.i = v }
f R S f
Go type switch
func f(p I) {
switch t := p.( type ) { 0.
case *S: 1.
case *R: 2.
case S: 3.
case R:

4.

default : 5.
}
}
0. switch (type) t
1. p S
2. p R
3. p S
4. p R
5. I

switch (type)
comma, ok

i f t, ok := something.(I) ; ok {
// I
// t

}
+

71

72

Chapter 5:

t := something.(I)

interface{}

Listing 5.2.
func g(something i n t e r f a c e { } ) i n t {
return something.(I).Get()
}
return something.(I).Get() something
interface{} .(I)
something I Get()
*S g() *S

s = new(S)
fmt.Println(g(s)) ;

g 0 g() I

Listing 5.3.
i := 5

i int

fmt.Println(g(i))

panic: interface conversion: int is not main.I: missing method Get

int Get()

2
int

type Foo i n t
func (self Foo) Emit() {
fmt.Printf("%v", self)

}
type Emitter i n t e r f a c e {
Emit()

73

Listing 5.4.
func (i i n t ) Emit() {

Listing 5.5.
func (a *net.AddrError) Emit() {

fmt.Printf("%d", i)

fmt.Printf("%v", a)

int

net.AddrError

invalid
receiver type ... [10]

T *T T T

Pointers to interfaces
Go
2010-10-13

[9]
var buf bytes.Buffer
io.Copy(buf, os.Stdin)

buf buf

-er ReaderWriterFormatter
ReadWriteClose
FlushString

String ToString
[8]

Q13

74

Chapter 5:

func bubblesort(n [] i n t ) {
f o r i := 0 ; i < len (n)-1 ; i++ {
f o r j := i + 1 ; j < len (n) ; j++ {
i f n[j] < n[i] {
n[i], n[j] = n[j], n[i]

}
}
}
}

func bubblesortString(n [] s t r i n g ) { /* ... */ }

func sort(i [] i n t e r f a c e { } ) { 0.
1.
switch i.( type ) {
case s t r i n g :

2.

// ...

case i n t :
// ...

}
return /* ... */ 3.
}

0. slice
1. type switch
2.
3. slice

sort([]int{1, 4, 5}) cannot use i (type


[]int) as type []interface

in function argument

Go slice
slice

[14]

Go slice
Go Go type switch

1. Sorter
slice

type Sorter i n t e r f a c e {
Len() i n t

len()

Less(i, j i n t ) bool

p[j]

Swap(i, j i n t )

p[i],

< p[i]
p[j] = p[j], p[i]

}
2. slice slice
type Xi [] i n t
type Xs [] s t r i n g
3. Sorter
func (p Xi) Len() i n t

{ return len (p) }

func (p Xi) Less(i int , j i n t ) bool { return p[j] < p[i] }


func (p Xi) Swap(i int , j i n t )

{ p[i], p[j] = p[j], p[i]

func (p Xs) Len() i n t

{ return len (p) }

func (p Xs) Less(i int , j i n t ) bool { return p[j] < p[i] }


func (p Xs) Swap(i int , j i n t )

{ p[i], p[j] = p[j], p[i]

}
4. Sorter
func Sort(x Sorter) { 0.
f o r i := 0 ; i < x.Len() - 1 ; i++ { 1.
f o r j := i + 1 ; j < x.Len() ; j++ {
i f x.Less(i, j) {
x.Swap(i, j)

}
}
}
}
0. x Sorter
1.

Sort
ints := Xi { 44, 67, 3, 17, 89, 10, 73, 9, 14, 8 }
strings := Xs { "nut", "ape", "elephant", "zoo", "go" }
Sort(ints)
fmt.Printf("%v\n", ints)
Sort(strings)
fmt.Printf("%v\n", strings)

75

76

Chapter 5:

container/heap
type Interface i n t e r f a c e {
sort.Interface
Push(x i n t e r f a c e { } )
Pop() i n t e r f a c e { }

}
heap.Interface
sort.Interface

Person namestr
reect Go
reect
Listing 5.6.
.
type Person s t r u c t {
name s t r i n g "namestr"
age

"namestr"

int

}
func ShowTag(i i n t e r f a c e { } ) {

*Person

switch t := reflect.TypeOf(i) ; t.Kind() {


case reflect.Ptr:
.

reflect.Ptr
.
.

0
1
2
tag := t.Elem().Field(0).Tag

0. We are dealing with a Type and according to the documentationa :

// Elem returns a types element type.


// It panics if the types Kind is not Array, Chan, Map, Ptr, or Slice.
Elem() Type

t Elem()
1.

Field(0)
2. StructField Tag 0th

.Tag Field(0).Tag namestr

a go doc reflect

Listing 5.7.
func show(i i n t e r f a c e { } ) {
switch t := i.( type ) {
case *Person:
t := reflect.TypeOf(i)


0.
tag := t.Elem().Field(0).Tag
name := v.Elem().Field(0).String() 1.
v := reflect.ValueOf(i)

}
}

0. Elem()

t reflect.Type

1.
v Elem() Field
(0) String()

Figure 5.1. Elem() *Person

go doc reflect string

reect.Ptr
reect.Value
reect.StructField

.Elem()
.Field(0)
.String()

"Albert Einstein"

"Albert Einstein"

77

78

Chapter 5:

Listing 5.8.
type Person s t r u c t {
name s t r i n g
age

Listing 5.9.
type Person s t r u c t {

Name s t r i n g

int

age

Name

int

func Set(i i n t e r f a c e { } ) {

func Set(i i n t e r f a c e { } ) {

switch i.( type ) {

switch i.( type ) {

case *Person:

case *Person:

r := reflect.ValueOf(i)

r := reflect.ValueOf(i)

r.Elem(0).Field(0).SetString("

r.Elem().Field(0).SetString("

Albert Einstein")

Albert Einstein")

panic: reflect.Value.SetString using value obtained using unexported


field

Name Albert Einstein


Set()

Q23. (1)
1. 72 5.3

Q24. (1)
1. 76

Name Albert Einstein


Set()

Q25. (2) max()


1. Q12 slice

A23. (1)
1.

5.2 Go g
func g(any i n t e r f a c e { } ) i n t { return any.(I).Get() }

func g(any i n t e r f a c e { } ) i n t {
i f v, ok := any.(I) ; ok {

//
// Get()

return v.Get()
}

//

return -1
}

g() Go comma
ok
A24. (1)
1. call-by-value

A25. (2) max()


1. Go
Listing 5.10.
package main
func Less(l, r i n t e r f a c e { } ) bool { 0.
switch l.( type ) {
case i n t :
i f _, ok := r.( i n t ) ; ok {
return l.( i n t ) < r.( i n t ) 1.
}
case float32 :
i f _, ok := r.( float32 ) ; ok {
return l.( float32 ) < r.( float32 ) 2.
}
}
return false
}
func main() {

79

80

Chapter 5:

var a, b, c i n t = 5, 15, 0
var x, y, z float32 = 5.4, 29.3, 0.0
i f c = a ; Less(a, b) { 3.
c = b

}
i f z = x ; Less(x, y) { 4.
z = y

}
println(c, z)

}
0. interface{}

1.
2. float32
3. a b
4.



Google IO 2010
ROB PIKE

Go channel goroutine goroutine Go


goroutine [8]

goroutine
goroutine goroutine

goroutine go
ready("Tea", 2)

go ready("Tea", 2)

ready() goroutine

[20] goroutine goroutine


14 15 goroutinemain
goroutine 17
5 goroutine
Listing 6.1. Go routine
func ready(w string , sec i n t ) {

time.Sleep(time.Duration(sec) * time.Second)

fmt.Println(w, "is ready ! ")

10

11

func main() {

13

go ready("Tea", 2)

14

go ready("Coffee", 1)

15

fmt.Println("I'm waiting")

16

time.Sleep(5 * time.Second)

17

18

6.1
I'm waiting

Coee is ready!

Tea is ready!

goroutine 17
goroutine goroutine
channels channel Unix sehll
channel channel
channel make channel
ci := make(chan i n t )
cs := make(chan s t r i n g )
cf := make(chan i n t e r f a c e { } )

channel ci channel cs channel cf


channel
<.
ci < 1

1 channel ci

<ci

channel ci

i := <ci

channel ci i

Listing 6.2. Go routines channel


var c chan i n t 0.
func ready(w string , sec i n t ) {
time.Sleep(time.Duration(sec) * time.Second)
fmt.Println(w, "is ready ! ")
c < 1

1.

}
func main() {
c = make(chan i n t ) 2.

go ready("Tea", 2) 3.
go ready("Coffee", 1)
fmt.Println("I'm waiting, but not too long")

<c 4.
<c 5.
}
0. c int channel channel

goroutine
1. 1 channel c
2. c
3. go goroutine
4. channel
5. goroutines

83

84

Chapter 6:

channel 14 15
goroutine
Go select select channel

select goroutine
14 15
Listing 6.3. select
L: f o r {

14

select {

15

case <c:

16

i++

17

if i > 1 {

18

break L

19

20

21

22

channel c L

goroutine Go
goroutine runtime.GOMAXPROCS(n)
goroutine

GOMAXPROCS CPU

n < 1
GOMAXPROCS

channel
Go ch := make(chan bool) chennel bool channel
value := <ch
ch<5
channel goroutine
Go channel channel
ch := make(chan bool, 4) 4 bool channel

channel 4 5
goroutine channel
Go true
{
ch := make(chan type, value)

value == 0
value > 0

value

channel
channel channel

x, ok = <ch

ok true channel ok
false channel

channel

Q26. (1) Channel


1. Q1
goroutine channel goroutine
2. 1 goroutine
main.main() main.main()
main.shower() 9

8 channela
Q27. (2) II
1. 34 10

1, 1, 2, 3, 5, 8, 13, . . . x1 =
1; x2 = 1; xn = xn1 + xn2

n > 2

int
channel

a select

85

A26. (1) Channel


1.
Listing 6.4. Go channel
package main

import "fmt"

func main() {

ch := make(chan i n t )

go shower(ch)

f o r i := 0 ; i < 10 ; i++ {

ch < i

10

11

func shower(c chan i n t ) {

13

for {

14

j := <c

15

fmt.Printf("%d\n", j)

16

17

18

6 int channel
shower ch for
8-10 < goroutine
shower shower 15

16 14
2.
Listing 6.5. channel
package main

import "fmt"

func main() {

ch := make(chan i n t )

quit := make(chan bool )

go shower(ch, quit)

f o r i := 0 ; i < 10 ; i++ {

ch < i

10

}
quit < false

11

// true

12
13

87

88

Chapter 6:

func shower(c chan int , quit chan bool ) {


for {

15
16

select {

17

case j := <c:

18

fmt.Printf("%d\n", j)

case <quit:
break
}

19
20
21
22

23

24

20 channel q := <quit
Go
_ = <quit Go 20 Go
A27. (2) II
1. channel
Listing 6.6. Go
package main
import "fmt"
func dup3(in <chan i n t ) (<chan int , <chan int , <chan i n t
) {
a, b, c := make(chan int , 2), make(chan int , 2),

make(chan int , 2)
go func () {
for {
x := <in
a < x
b < x
c < x

}
} ()
return a, b, c
}
func fib() <chan i n t {
x := make(chan int , 2)
a, b, out := dup3(x)

go func () {
x < 0
x < 1

<a
for {

x < <a+<b

}
} ()
return out
}
func main() {
x := fib()

f o r i := 0 ; i < 10 ; i++ {
fmt.Println(<x)

}
}
// See sdh33b.blogspot.com/2009/12/fibonacci-in-go.html

89

ANNE MORROW LINDBERGH

Go
Go I/O io.Reader io.Writer
Go os
/etc/passwd

Listing 7.1.
package main
import "os"
func main() {
buf := make([] byte , 1024)
f, _ := os.Open("/etc/passwd") 0.

defer f.Close() 1.
for {
n, _ := f.Read(buf) 2.

i f n == 0 { break } 3.
os.Stdout.Write(buf[:n]) 4.

}
}

0. os.Open io.Reader io.Writer *os.File


1. f
2. 1024
3.
4. os.Stdout

IO buo
Listing 7.2.
package main
import ( "os" ; "bufio")
func main() {

io.Reader

buf := make([] byte , 1024)


f, _ := os.Open("/etc/passwd") 0.

defer f.Close()
r := bufio.NewReader(f) 1.

w := bufio.NewWriter(os.

Stdout)

defer w.Flush()
for {
n, _ := r.Read(buf)

2.

i f n == 0 { break }
w.Write(buf[0:n])

}
}

0.
1. f ReaderNewReader io.Reader

Read()
7.1*os.File
2. Reader Writer

io.Reader
io.Reader Go
io.Reader
Read(p []byte) (n int, err error)
Write io.Writer
io.Reader io.Writer Go

f, _ := os.Open("/etc/passwd") ; defer f.Close()


r := bufio.NewReader(f)

buo ReadString

s, ok := r.ReadString('\n') {
// ... |

s string |

ReadLine buo
shell

91

92

Chapter 7:

Listing 7.4. Go

Listing 7.3. shell

i f f, e := os.Stat("name") ; e ! =

i f [ ! -e name ] ; then

nil {

mkdir name

os.Mkdir("name", 0755)

else

} else {

# error

// error

fi

Go Go
PythonRubyPerl PHP

slice os.Args os ag
DNS
dnssec := flag.Bool("dnssec", false, "Request DNSSEC records") 0.
port := flag.String("port", "53", "Set the query port")
flag.Usage = func () {

1.

2.

fmt.Fprintf(os.Stderr, "Usage: %s [OPTIONS] [name ...]\n", os.


Args[0])
flag.PrintDefaults() 3.

}
flag.Parse()

4.

0. bool -dnssec package


1. port
2. Usage
3. PrintDefaults
4.

i f *dnssec {

dnssec

//

os/exec Go
*exec.Cmd
ls -l
import "os/exec"

cmd := exec.Command("/bin/ls", "-l")


err := cmd.Run()

ls -l

import "exec"
cmd := exec.Command("/bin/ls", "-l")
buf, err := cmd.Output()

buf []byte

net Dial
Dial Conn
Dial IPv4 IPv6TCP UDP

TCP 80 UDP TCP IPv6


a
conn, e := Dial("tcp", "192.0.32.10:80")
conn, e := Dial("udp", "192.0.32.10:80")
conn, e := Dial("tcp", "[2620:0:2d0:200::10]:80")


e conn net

// Read reads data from the connection.


Read(b []byte)(n int, err error)

conn io.Reader
// Write writes data to the connection.
Write(b []byte)(n int, err error)

conn io.Writer conn io.ReadWriterb


c http
http Get
package main
import ( "io/ioutil" ; "net/http" ; "fmt" ) 0.
func main() {
r, err := http.Get("http://www.google.com/robots.txt") 1.

i f err ! = nil { fmt.Printf("%s\n", err.String()) ; return } 2.


a

192.0.32.10 2620:0:2d0:200::10 www.example.org

b conn close io.ReadWriteCloser


c Q32

93

94

Chapter 7:

b, err := ioutil.ReadAll(r.Body)

3.

r.Body.Close()

i f err == nil { fmt.Printf("%s", s t r i n g (b)) } 4.


}
0.
1. http Get html
2.
3. b
4. OK

Q28. (2)
1.

Pid 0 has 2 children: [1 2]


Pid 490 has 2 children: [1199 26524]
Pid 1824 has 1 child: [7293]

ps -e -opid,ppid,comm

PID

PPID COMMAND

9024

9023 zsh

19560

9024 ps

child
children

pid 0
Perl
Listing 7.5. Perl
# ! /usr/bin/perl -l
my (%child, $pid, $parent) ;
my @ps=`ps -e -opid,ppid,comm` ;

# Capture the output

from `ps`
foreach (@ps[1..$#ps]) {

# Discard the header

line
($pid, $parent, undef) = split ; # Split the line,
discard 'comm'
push @ { $child { $parent } } , $pid ;
a list

# Save the child PIDs on

}
# Walk through the sorted PPIDs
foreach (sort { $a <=> $b } keys %child) {
print "Pid ", $_, " has ", @ { $child { $_ } } +0, " child",
@ { $child { $_ } } == 1 ? ": " : "ren: ", "[@ { $child { $_ } }
]" ;

Q29. (0)
1.
1.
2.
3.
wc(1)

Q30. (0) Uniq


1. Go Unix uniq

'a' 'b' 'a' 'a' 'a' 'c' 'd' 'e' 'f' 'g'

'a' 'b' 'a' 'c' 'd' 'e' 'f'

7.8 Perl
Listing 7.8. uniq(1) Perl
#!/usr/bin/perl

my @a = qw/a b a a a c d e f g/ ;
p r i n t my $first = s h i f t @a ;
foreach (@a) {
i f ($first ne $_) { p r i n t ; $first = $_ ; }
}

Q31. (2) Quine

Quine

1. Go Quine
Q32. (1) Echo
1. echo TCP 8053

2. goroutine
Q33. (2)

95

96

Chapter 7:


1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100

1 . . . 1000 i
+ / i
16788 75 i 977

((((1 6) 8) + 75) 8) 7 = 977

(8 (75 + (8 6))) (7/1) = 977


1.

2.
544
Q34. (1) *Finger
1. nger nger(1)
Debian
Fingerd RFC 1196 [28]

nger

.plan


.plan

A28. (2)
1.
1. ps
2. PPID PID
3. PPID
4.
map[int][]int map
slice PID append
slice

Listing 7.6. Go
package main
import ( "fmt" ; "os/exec" ; "sort" ; "strconv" ; "strings")
func main() {
ps := exec.Command("ps", "-e", "-opid,ppid,comm")
output, _ := ps.Output()
child := make(map[ i n t ][] i n t )

f o r i, s := range strings.Split( s t r i n g (output), "\n"


) {

i f i == 0 { continue } // Kill first line


i f len (s) == 0 { continue } // Kill last line
f := strings.Fields(s)
fpp, _ := strconv.Atoi(f[1]) // pid
fp, _ := strconv.Atoi(f[0])

// pid

child[fpp] = append(child[fpp], fp)

}
schild := make([] int , len (child))
i := 0

f o r k, _ := range child { schild[i] = k ; i++ }


sort.Ints(schild)

f o r _, ppid := range schild {


fmt.Printf("Pid %d has %d child", ppid, len (
child[ppid]))

i f len (child[ppid]) == 1 {
fmt.Printf(": %v\n", child[ppid])

continue
}
fmt.Printf("ren: %v\n", child[ppid])

97

98

Chapter 7:

}
}

A29. (0)
1. wc(1)
Listing 7.7. wc(1) Go
package main
import (
"os"
"fmt"
"bufio"
"strings"
)

func main() {
var chars, words, lines i n t
r := bufio.NewReader(os.Stdin) 0.

for {
switch s, ok := r.ReadString('\n') ; true { 1.
case ok ! = nil: 2.
fmt.Printf("%d %d %d\n", chars,
words, lines) ;

return
3.

default :

chars += len (s)


words += len (strings.Fields(s))
lines++

}
}
}
0. Start a new reader that reads from standard input;
1. Read a line from the input;
2. If we received an error, we assume it was because of a EOF. So we print the

current values;
3. Otherwise we count the charaters, words and increment the lines.

A30. (0) Uniq


1. uniq Go .
Listing 7.9. uniq(1) Go
package main

import "fmt"
func main() {
list := [] s t r i n g { "a", "b", "a", "a", "c", "d", "e",
"f" }
first := list[0]
fmt.Printf("%s ", first)

f o r _, v := range list[1:] {
i f first ! = v {
fmt.Printf("%s ", v)
first = v

}
}
}

A31. (2) Quine


Russ Cox Go Nuts

Listing 7.10. Go quine


1. /* Go quine */
package main
import "fmt"
func main() {
fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)

}
var q = `/* Go quine */
package main
import "fmt"
func main() {
fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)

}
var q = `

A32. (1) Echo


1. echo
Listing 7.11. echo
package main
import ( "net" ; "fmt" ; "bufio" )

99

100

Chapter 7:

func main() {
l, err := net.Listen("tcp", "127.0.0.1:8053")

i f err ! = nil {
fmt.Printf("Failure to listen: %s\n", err.
Error())

}
for {
i f c, err := l.Accept() ; err == nil { Echo(c
) }

}
}
func Echo(c net.Conn) {
defer c.Close()
line, err := bufio.NewReader(c).ReadString('\n')

i f err ! = nil {
fmt.Printf("Failure to read: %s\n", err.
Error())

return
}
_, err = c.Write([] byte (line))

i f err ! = nil {
fmt.Printf("Failure to write: %s\n", err.
Error())

return
}
}

% nc 127.0.0.1 8053
Go is *awesome*
Go is *awesome*

2.
i f c, err := l.Accept() ; err == nil { Echo(c) }

i f c, err := l.Accept() ; err == nil { go Echo(c) }

A33. (2)
1.
Listing 7.12.
package main
import ( "fmt" ; "strconv" ; "flag")

const (
_ = 1000 * i o t a
ADD
SUB
MUL
DIV
MAXPOS = 11
)

var mop = map[ i n t ] s t r i n g { ADD: "+", SUB: "-", MUL: "*", DIV:
"/" }

var (
ok

bool

value i n t
)

type Stack s t r u c t {
i

int

data [MAXPOS] i n t

}
func (s *Stack) Reset()

{ s.i = 0 }

func (s *Stack) Len() i n t

{ return s.i }

func (s *Stack) Push(k i n t ) { s.data[s.i] = k ; s.i++ }


func (s *Stack) Pop() i n t

{ s.i-- ; return s.data[s.i] }

var found i n t
var stack = new(Stack)
func main() {
flag.Parse()
list := [] i n t { 1, 6, 7, 8, 8, 75, ADD, SUB, MUL, DIV }
magic, ok := strconv.Atoi(flag.Arg(0))

// Arg0 i

i f ok ! = nil { return }
f := make([] int , MAXPOS)
solve(f, list, 0, magic)

}
func solve(form, numberop [] int , index, magic i n t ) {
var tmp i n t

101

102

Chapter 7:

f o r i, v := range numberop {
i f v == 0 { goto NEXT }
i f v < ADD { //
tmp = numberop[i]
numberop[i] = 0

}
form[index] = v
value, ok = rpncalc(form[0 : index+1])

i f ok && value == magic {


i f v < ADD {
numberop[i] = tmp //

}
found++
fmt.Printf("%s = %d

#%d\n", rpnstr(

form[0:index+1]), value, found)

}
i f index == MAXPOS-1 {
i f v < ADD {
numberop[i] = tmp //

}
goto NEXT
}
solve(form, numberop, index+1, magic)

i f v < ADD {
numberop[i] = tmp //

}
NEXT:

}
}
func rpnstr(r [] i n t ) (ret s t r i n g ) { // rpn
s := make([] string , 0) //

f o r k, t := range r {
switch t {
case ADD, SUB, MUL, DIV:
a, s := s[ len (s)-1], s[: len (s)-1]
b, s := s[ len (s)-1], s[: len (s)-1]

i f k == len (r)-1 {
s = append(s, b+mop[t]+a)

} else {
s = append(s, "("+b+mop[t]+a

+")")

}
default :
s = append(s, strconv.Itoa(t))

}
}
f o r _, v := range s { ret += v }
return
}
func rpncalc(r [] i n t ) ( int , bool ) {
stack.Reset()

f o r _, t := range r {
switch t {
case ADD, SUB, MUL, DIV:
i f stack.Len() < 2 { return 0, false
}
a := stack.Pop()
b := stack.Pop()

i f t == ADD { stack.Push(b + a) }
i f t == SUB {
//

i f b-a < 0 {
return 0, false
}
stack.Push(b - a)

}
i f t == MUL { stack.Push(b * a) }
i f t == DIV {
i f a == 0 {
return 0, false
}
//

i f b%a ! = 0 {
return 0, false
}
stack.Push(b / a)

}
default :
stack.Push(t)

}
}
i f stack.Len() == 1 { //
return stack.Pop(), true
}

103

104

Chapter 7:

return 0, false
}
2. permrec 977
% ./permrec 977
1+(((6+7)*75)+(8/8)) = 977

#1

...

...

((75+(8*6))*8)-7 = 977

#542

(((75+(8*6))*8)-7)*1 = 977

#543

(((75+(8*6))*8)-7)/1 = 977

#544

A34. (1) *Finger


Fabian Becker
Listing 7.13. nger
1. package main
import (
"bufio"
"errors"
"flag"
"io/ioutil"
"net"
"os/user"
"strconv"
)

func main() {
flag.Parse()
ln, err := net.Listen("tcp", ":79")

i f err ! = nil {
panic(err)

}
for {
conn, err := ln.Accept()

i f err ! = nil {
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
usr, _, _ := reader.ReadLine()

i f info, err := getUserInfo( s t r i n g (usr)) ; err ! = nil


{
conn.Write([] byte (err.Error()))

} else {
conn.Write(info)

}
}
func getUserInfo(usr s t r i n g ) ([] byte , e r r o r ) {
u, e := user.Lookup(usr)

i f e ! = nil {
return nil, e
}
data, err := ioutil.ReadFile(u.HomeDir + ".plan")

i f err ! = nil {
return data, errors.New("User doesn't have a
.plan file ! \n")

}
return data, nil
}

105

LATEX Google Droid DejaVu


Mono UKai

Miek Gieben

<miek@miek.nl>

JC van Winkel

Adam J.
GrayAlex SychevAlexey ChernenkovAndrea SpadacciniAndrey MirtchovskiAnthony
MagroBabu SreekanthBen BullockBob CunninghamBrian FallikCecil NewDamian
GryskiDan KortschakDavid OttonFabian BeckerFilip ZaludekHadi AmiriHaiping
FanJaap AkkerhuisJC van WinkelJeroen BultenJinpu HuJohn ShahidJonathan
KansJoshua SteinMakoto InoueMayuresh KathememMichael StapelbergOlexandr
ShalakhinPaulo PintoPeter KleiwegPhilipp SchmidtRobert JohnsonRussel Winder
Sonia KeysStefan SchroederThomas KappletT.J. YangCoboldSimocUriel

Alexander
Katasonov, Daniele Pala, Iaroslav Tymchenko, Nicolas Kaiser, Marco Ynema.
Miek Gieben

Miek Gieben DNSSEC


DNSDNSSEC protocol [6] Erlang Go
Go Go DNS
https://github.com/miekg/dns http://www.miek.nl
Twitter @miekg Go

http://mikespook.com Twitter @mikespook

- - 3.0 Unported
http://creativecommons.org/licenses/by-nc-sa/3.0/

Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105,
USA

Miek Gieben 2010:2012


20112012

107

array

generic, 74

capacity, 15

goroutine, 82

length, 15

goroutines, 2

multidimensional, 15
interface, 70
buffered, 90

set of methods, 70

built-in

type, 70

append, 14, 17
cap, 14

value, 70
io.Reader, 91

close, 14
complex, 14

keyword

copy, 14, 18

break, 9, 10

delete, 14

continue, 11

imag, 14

default, 12

len, 14

defer, 29

make, 14, 54

else, 9

new, 14, 54

fallthrough, 12

panic, 14

for, 10

print, 14

go, 82

println, 14

goto, 10

real, 14

if, 8

recover, 14

import, 45
iota, 5

channel, 2, 83

map, 18

blocking read, 84

add elements, 18

blocking write, 84

existence, 18

non-blocking read, 84

remove elements, 19

non-blocking write, 84

package, 44

unbuffered, 84

range, 11, 18

channels, 83

on maps, 11, 18

closure, 30

on slices, 11

complex numbers, 14

return, 9
select, 84

deferred list, 30

struct, 57

duck typing, 70

switch, 12
type, 57

eld
anonymous, 58
elds, 56
function

label, 10
literal
composite, 15, 56

as values, 31
call, 58

method call, 58

literal, 30

methods

literals, 31

inherited, 59

Index

MixedCaps, 46

runes, 11

named return parameters, 26

scope
local, 27

networking
Dial, 93

slice
capacity, 15

nil, 54

length, 15
operator

string literal

address-of, 54

interpreted, 6

and, 7

raw, 6

bit wise xor, 7


bitwise
and, 7
clear, 7
or, 7
channel, 83
increment, 54

toolin
go
test, 47
tooling
go, 3
build, 3

not, 7

type assertion, 72

or, 7

type switch, 71

package

variables

buo, 46, 49, 90

_, 4

builtin, 14

assigning, 4

bytes, 45

declaring, 4

compress/gzip, 46

underscore, 4

encoding/json, 49

, 58

even, 44
ag, 49
fmt, 14, 49
html/template, 49
io, 49, 91
net/http, 49
os, 49
os/exec, 50, 92
reect, 50, 76
ring, 46
sort, 49
strconv, 49
sync, 49
unsafe, 49
parallel assignment, 4, 10
pass-by-value, 26
private, 45
public, 45
receiver, 26
reference types, 15

, 26

109

Bibliography

[1]

Haskell Authors. Haskell. http://www.haskell.org/, 1990.

[2]

D. Crockford. The application/json media type for javascript object notation (json).
http://www.ietf.org/rfc/rfc4627.txt, 2006.

[3]

Brian Kernighan Dennis Ritchie. The C programming language, 1975.

[4]

Ericsson Cooperation. Erlang. http://www.erlang.se/, 1986.

[5]

Larry Wall et al. Perl. http://perl.org/, 1987.

[6]

Kolkman & Gieben. Dnssec operational practices. http://www.ietf.org/rfc/


rfc4641.txt, 2006.

[7]

Go Authors.

Defer, panic, and recover.

http://blog.golang.org/2010/08/

defer-panic-and-recover.html, 2010.

[8]

Go Authors. Effective Go. http://golang.org/doc/effective_go.html, 2010.

[9]

Go Authors. Go faq. http://golang.org/doc/go_faq.html, 2010.

[10] Go Authors. Go language specication. http://golang.org/doc/go_spec.html,


2010.
[11] Go Authors. Go package documentation. http://golang.org/doc/pkg/, 2010.
[12] Go Authors. Go tutorial. http://golang.org/doc/go_tutorial.html, 2010.
[13] Go Authors. Go website. http://golang.org/, 2010.
[14] Go Community.

Function accepting a slice of interface types.

http:

//groups.google.com/group/golang-nuts/browse_thread/thread/
225fad3b5c6d0321, 2010.

[15] James Gosling et al. Java. http://oracle.com/java/, 1995.


[16] LAMP Group at EPFL. Scala. http://www.scala-lang.org/, 2003.
[17] C. A. R. Hoare. Quicksort. http://en.wikipedia.org/wiki/Quicksort, 1960.
[18] C. A. R. Hoare. Communicating sequential processes (csp). http://www.usingcsp.
com/cspbook.pdf, 1985.

[19] Rob Pike.

The Go programming language, day 2.

http://golang.org/doc/

{G}oCourseDay2.pdf, 2010.

[20] Rob Pike.

The Go programming language, day 3.

http://golang.org/doc/

{G}oCourseDay3.pdf, 2010.

[21] Bjarne Stroustrup. The C++ programming language, 1983.


[22] Ian Lance Taylor. Go interfaces. http://www.airs.com/blog/archives/277,
2010.

Bibliography

[23] Imran On Tech. Using zzbuzz to nd developers... http://imranontech.com/


2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/,

2010.
[24] Wikipedia. Bubble sort. http://en.wikipedia.org/wiki/Bubble_sort, 2010.
[25] Wikipedia. Communicating sequential processes. http://en.wikipedia.org/
wiki/Communicating_sequential_processes, 2010.

[26] Wikipedia. Duck typing. http://en.wikipedia.org/wiki/Duck_typing, 2010.


[27] Wikipedia. Iota. http://en.wikipedia.org/wiki/Iota, 2010.
[28] D. Zimmerman. The nger user information protocol. http://www.ietf.org/rfc/
rfc1196.txt, 1990.

111

Anda mungkin juga menyukai