Skip to content

Commit 2fc6e8b

Browse files
committed
Moved chapter 3. Added 4 and 5.
1 parent dd4736e commit 2fc6e8b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+916
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
In the original version of Go In Practice, we wrote an entire chapter on
2+
dependency management. But during the course of writing the book, Go 1.5
3+
was released, which (in our opinion) solves most of the problems we were
4+
dealing with when we first wrote the book.

chapter4/closure_scope.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
var msg string
7+
defer func() {
8+
fmt.Println(msg)
9+
}()
10+
msg = "Hello world"
11+
}

chapter4/data.csv

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
one,two
2+
hello,world
3+
goodbye,world

chapter4/error_example.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"strings"
8+
)
9+
10+
// Concat concatenates a bunch of strings.
11+
// Strings are separated by spaces.
12+
// It returns an empty string and an error if no strings were passed in.
13+
func Concat(parts ...string) (string, error) {
14+
if len(parts) == 0 {
15+
return "", errors.New("No strings supplied")
16+
}
17+
18+
return strings.Join(parts, " "), nil
19+
}
20+
21+
func main() {
22+
23+
args := os.Args[1:]
24+
25+
/*
26+
if result, err := Concat(args...); err != nil {
27+
fmt.Printf("Error: %s\n", err)
28+
} else {
29+
fmt.Printf("Concatenated string: '%s'\n", result)
30+
}
31+
*/
32+
result, _ := Concat(args...)
33+
fmt.Printf("Concatenated string: '%s'\n", result)
34+
35+
}
36+
37+
func assumeGoodDesign() {
38+
// Streamlined error handling
39+
batch := []string{}
40+
result, _ := Concat(batch...)
41+
fmt.Printf("Concatenated string: '%s'\n", result)
42+
43+
}

chapter4/http_server.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"net/http"
6+
)
7+
8+
func main() {
9+
http.HandleFunc("/", handler)
10+
http.ListenAndServe(":8080", nil)
11+
}
12+
func handler(res http.ResponseWriter, req *http.Request) {
13+
panic(errors.New("Fake panic!"))
14+
}

chapter4/parser_error.go

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
7+
err := &ParseError{
8+
Message: "Unexpected char ';'",
9+
Line: 5,
10+
Char: 38,
11+
}
12+
13+
fmt.Println(err.Error())
14+
}
15+
16+
type ParseError struct {
17+
Message string
18+
Line, Char int
19+
}
20+
21+
func (p *ParseError) Error() string {
22+
format := "%s on Line %d, Char %d"
23+
return fmt.Sprintf(format, p.Message, p.Line, p.Char)
24+
}

chapter4/proper_panic.go

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
import "errors"
4+
5+
func main() {
6+
panic(errors.New("Something bad happened."))
7+
}

chapter4/recover_panic.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
func main() {
9+
msg := "Everything's fine"
10+
defer func() {
11+
if err := recover(); err != nil {
12+
fmt.Printf("Trapped panic: %s (%T)\n", err, err)
13+
}
14+
fmt.Println(msg)
15+
}()
16+
17+
yikes()
18+
}
19+
20+
func yikes() {
21+
panic(errors.New("Something bad happened."))
22+
}

chapter4/safely/safely.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package safely
2+
3+
import (
4+
"log"
5+
)
6+
7+
type GoDoer func()
8+
9+
func Go(todo GoDoer) {
10+
go func() {
11+
defer func() {
12+
if err := recover(); err != nil {
13+
log.Printf("Panic in safely.Go: %s", err)
14+
}
15+
}()
16+
todo()
17+
}()
18+
}

chapter4/safely_example.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
import (
4+
"./safely"
5+
"errors"
6+
"time"
7+
)
8+
9+
func message() {
10+
println("Inside goroutine")
11+
panic(errors.New("Oops!"))
12+
}
13+
14+
func main() {
15+
safely.Go(message)
16+
println("Outside goroutine")
17+
time.Sleep(200)
18+
}

chapter4/same_error.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import "errors"
4+
5+
func main() {
6+
errA := errors.New("Error")
7+
//errB := errors.New("Error")
8+
9+
if errA != errA {
10+
panic("Expected same!")
11+
}
12+
println("Done")
13+
}

chapter4/simple_defer.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
defer goodbye()
7+
8+
fmt.Println("Hello world.")
9+
}
10+
11+
func goodbye() {
12+
fmt.Println("Goodbye")
13+
}

chapter4/simple_server.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"errors"
6+
"fmt"
7+
"net"
8+
)
9+
10+
func main() {
11+
listen()
12+
}
13+
14+
func listen() {
15+
listener, err := net.Listen("tcp", ":1026")
16+
if err != nil {
17+
fmt.Println("Failed to open port on 1026")
18+
return
19+
}
20+
for {
21+
conn, err := listener.Accept()
22+
if err != nil {
23+
fmt.Println("Error accepting connection")
24+
continue
25+
}
26+
27+
go handle(conn)
28+
}
29+
}
30+
31+
func handle(conn net.Conn) {
32+
defer func() {
33+
if err := recover(); err != nil {
34+
fmt.Printf("Fatal error: %s", err)
35+
}
36+
conn.Close()
37+
}()
38+
reader := bufio.NewReader(conn)
39+
40+
data, err := reader.ReadBytes('\n')
41+
if err != nil {
42+
fmt.Println("Failed to read from socket.")
43+
}
44+
45+
response(data, conn)
46+
}
47+
48+
func response(data []byte, conn net.Conn) {
49+
conn.Write(data)
50+
panic(errors.New("Pretend I'm a real error"))
51+
}

chapter4/simple_server_start.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"errors"
6+
"fmt"
7+
"net"
8+
)
9+
10+
func main() {
11+
listen()
12+
}
13+
14+
func listen() {
15+
defer func() {
16+
if err := recover(); err != nil {
17+
fmt.Printf("Caught a panic and recovered")
18+
}
19+
}()
20+
listener, err := net.Listen("tcp", ":1026")
21+
if err != nil {
22+
fmt.Println("Failed to open port on 1026")
23+
return
24+
}
25+
for {
26+
conn, err := listener.Accept()
27+
if err != nil {
28+
fmt.Println("Error accepting connection")
29+
continue
30+
}
31+
32+
go handle(conn)
33+
}
34+
}
35+
36+
func handle(conn net.Conn) {
37+
reader := bufio.NewReader(conn)
38+
39+
data, err := reader.ReadBytes('\n')
40+
if err != nil {
41+
fmt.Println("Failed to read from socket.")
42+
conn.Close()
43+
}
44+
45+
response(data, conn)
46+
}
47+
48+
func response(data []byte, conn net.Conn) {
49+
defer func() {
50+
conn.Close()
51+
}()
52+
conn.Write(data)
53+
panic(errors.New("Failure in response!"))
54+
}

chapter4/two_defers.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package main
2+
3+
func main() {
4+
defer func() { println("a") }()
5+
defer func() { println("b") }()
6+
}

chapter4/two_errors.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"math/rand"
7+
)
8+
9+
var ErrTimeout = errors.New("The request timed out")
10+
var ErrRejected = errors.New("The request was rejected")
11+
12+
var random = rand.New(rand.NewSource(35))
13+
14+
//var random = rand.New(rand.NewSource(78))
15+
16+
func main() {
17+
response, err := SendRequest("Hello")
18+
for err == ErrTimeout {
19+
fmt.Println("Timeout. Retrying.")
20+
response, err = SendRequest("Hello")
21+
}
22+
if err != nil {
23+
fmt.Println(err)
24+
} else {
25+
fmt.Println(response)
26+
}
27+
}
28+
29+
func SendRequest(req string) (string, error) {
30+
31+
switch random.Int() % 3 {
32+
case 0:
33+
return "Success", nil
34+
case 1:
35+
return "", ErrRejected
36+
default:
37+
return "", ErrTimeout
38+
}
39+
}

0 commit comments

Comments
 (0)