Miek Gieben
Go Google
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
2011 - 2013
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
19
(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
20
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.
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
1.
shell %
shell
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
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.
/* 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 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 :=
a b 20 a16 b
_ 35
b 34
_, b := 34, 35
Go i
package main
func main() {
var i i n t
}
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
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
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
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
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
}
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
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)
11
12
Chapter 1:
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
, as or
return true
}
return false
}
switch
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
imag
cap
copy
println
f go doc builtin
13
14
Chapter 1:
Go builtin
close
channel channel 6
delete
map
len cap
new 55
make
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])
arrayslices map
15
var a [3]int
a := [3]int{1, 2, 3} a := [...]int{1, 2, 3}Go
array slice
56
map
array (...)
map
slice
slice array slice
arrayslice array array slice
slice array
slice slice
make
array
sl := make([] int , 10)
16
Chapter 1:
n-1
...
m-1
array
len == cap == m
n-1
...
len == n
m-1
slice
cap == m
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() {
slice := array[0:99]
slice[98] = 'a'
OK
slice[99] = 'a'
Error:
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:
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
== 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"])
year := 0
_,
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")
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
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.
f o r i := 0 ; i < 10 ; i++ {
arr[i] = i
}
fmt.Printf("%v", arr)
21
22
Chapter 1:
a := [...] i n t { 0,1,2,3,4,5,6,7,8,9 }
Go
fmt.Printf("%v\n", a)
var p bool
1.
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"
String concatenation
}
}
2. unicode/utf8 go doc
unicode/utf8 | less func RuneCount(p []
str := "hello"
b
:= [] byte (str)
59
func main() {
str := "dsjkdshdjsdh....js"
fmt.Printf("String %s\nLength: %d, Runes: %d\n", str,
23
24
Chapter 1:
package main
import (
"fmt"
)
3. func main() {
s := "
"
r := [] rune (s)
}
4. ij
Again a conversion
a := [] rune (s)
Parallel assignment
}
fmt.Printf("%s\n", s t r i n g (a))
Convert it back
A4. (1)
1.
sum := 0.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
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)
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
}
i f failureX {
file.Close()
return false
}
i f failureY {
file.Close()
return false
}
file.Close()
return true
}
Go defer defer
Close Open
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
ret
defer func () {
ret++
ret 1
} ()
return 0
1 0
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)
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
Eleanor McHugh
1. recover defer goroutine panic
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
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()
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
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
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
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) 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:
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.
}
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
return i % 2 == 0
}
$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))
US ASCII
Go
Go
Atoi
GetwdChmod
ReadFileNewWriterMakeSlice
import
import "bytes"
bytes.Buffer
45
46
Chapter 3:
src/pkg/compress/gzip compress/gzip
gzip compress_gzip compressGzip
Go MixedCaps mixedCaps
[8]
package
go doc
regexp
/*
The regexp package implements a simple library for
regular expressions.
regexp:
concatenation
'|' concatenation
*/
package regexp
fmt
Go testing go
test
go test even go test
% go test
?
even
*_test.go Go go test
Test
func TestXxx(t *testing.T)
go test
[11] go doc testing go
help testfunc
even_test.go
import "testing"
i f ! Even(2) {
}
}
t.Fail()
8
9
10
47
48
Chapter 3:
package even
testing
5 Go
Even
% go test
ok
even
0.001s
ok
}
}
FAIL
even
0.004s
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
type Stack s t r u c t {
i
int
data [10] i n t
}
// Push
}
// Pop
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"
)
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 == '+':
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 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
slice
var v
v 100
55
56
Chapter 4:
new make
new(T) *T T
make(T) T
make slicemap channel
os
return f
}
return &f
b
return &File { fd, name, nil, 0 }
The items (called of a composite +literal are laid out in order and must all be
:
new(File) &File{}
arrayslice map map
EnoneEio Einval
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]
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 */ }
{ /* Lock */ }
{ /* Unlock */ }
Mutex
Go
byte()
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)
59
60
Chapter 4:
:= [] rune (mystring)
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)
type foo s t r u c t { i n t }
bar foo
b bar
var f foo = b
b f
foo )
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
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
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)
}
}
2. The following is a program implementing a simple doubly linked list supporting
int values.
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.
} 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)
}
fmt.Println()
}
}
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"
)
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 {
}
}
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
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
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))
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 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
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
}
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
reflect.Ptr
.
.
0
1
2
tag := t.Elem().Field(0).Tag
t Elem()
1.
Field(0)
2. StructField Tag 0th
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()
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 { } ) {
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")
Q23. (1)
1. 72 5.3
Q24. (1)
1. 76
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
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
goroutine
goroutine goroutine
goroutine go
ready("Tea", 2)
go ready("Tea", 2)
ready() goroutine
time.Sleep(time.Duration(sec) * time.Second)
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 { } )
1 channel ci
<ci
channel ci
i := <ci
channel ci i
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
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
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
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 )
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:
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
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.
}
}
IO buo
Listing 7.2.
package main
import ( "os" ; "bufio")
func main() {
io.Reader
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
buo ReadString
s, ok := r.ReadString('\n') {
// ... |
s string |
ReadLine buo
shell
91
92
Chapter 7:
Listing 7.4. Go
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.
}
flag.Parse()
4.
i f *dnssec {
dnssec
//
os/exec Go
*exec.Cmd
ls -l
import "os/exec"
ls -l
import "exec"
cmd := exec.Command("/bin/ls", "-l")
buf, err := cmd.Output()
buf []byte
net Dial
Dial Conn
Dial IPv4 IPv6TCP UDP
e conn net
conn io.Reader
// Write writes data to the connection.
Write(b []byte)(n int, err error)
93
94
Chapter 7:
b, err := ioutil.ReadAll(r.Body)
3.
r.Body.Close()
Q28. (2)
1.
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` ;
from `ps`
foreach (@ps[1..$#ps]) {
line
($pid, $parent, undef) = split ; # Split the line,
discard 'comm'
push @ { $child { $parent } } , $pid ;
a list
}
# 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)
'a' 'b' 'a' 'a' 'a' 'c' 'd' 'e' 'f' 'g'
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 = $_ ; }
}
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
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 )
// pid
}
schild := make([] int , len (child))
i := 0
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 :
}
}
}
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.
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
}
}
}
}
var q = `/* Go quine */
package main
import "fmt"
func main() {
fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
}
var q = `
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) }
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 }
{ return 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])
}
found++
fmt.Printf("%s = %d
#%d\n", rpnstr(
}
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
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()
} 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
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
- - 3.0 Unported
http://creativecommons.org/licenses/by-nc-sa/3.0/
Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105,
USA
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
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
toolin
go
test, 47
tooling
go, 3
build, 3
not, 7
type assertion, 72
or, 7
type switch, 71
package
variables
_, 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]
[2]
D. Crockford. The application/json media type for javascript object notation (json).
http://www.ietf.org/rfc/rfc4627.txt, 2006.
[3]
[4]
[5]
[6]
[7]
Go Authors.
http://blog.golang.org/2010/08/
defer-panic-and-recover.html, 2010.
[8]
[9]
http:
//groups.google.com/group/golang-nuts/browse_thread/thread/
225fad3b5c6d0321, 2010.
http://golang.org/doc/
{G}oCourseDay2.pdf, 2010.
http://golang.org/doc/
{G}oCourseDay3.pdf, 2010.
Bibliography
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.
111