├── .DS_Store
├── .idea
├── book.iml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── README.md
├── ch03
├── 3.1
│ ├── array
│ │ └── main.go
│ └── strings
│ │ └── main.go
├── 3.2
│ ├── append
│ │ └── main.go
│ ├── copy
│ │ └── main.go
│ └── slicebase
│ │ └── main.go
├── 3.3
│ └── main.go
└── 3.4
│ ├── compli
│ └── main.go
│ └── pointer
│ └── main.go
├── ch04
├── 4.1
│ ├── argu
│ │ └── main.go
│ ├── clo
│ │ └── main.go
│ └── clo2
│ │ └── main.go
├── 4.2
│ ├── base
│ │ └── main.go
│ ├── extends
│ │ └── main.go
│ └── pointer
│ │ └── main.go
├── 4.3
│ ├── adv
│ │ └── main.go
│ └── base
│ │ └── myinterface.go
└── 4.4
│ ├── adv
│ └── main.go
│ └── main.go
├── ch05
├── 5.1
│ ├── adv1
│ │ └── main.go
│ ├── adv2
│ │ └── main.go
│ ├── base
│ │ └── main.go
│ └── sync
│ │ └── main.go
├── 5.2
│ ├── buffer
│ │ └── main.go
│ ├── read
│ │ └── main.go
│ ├── select
│ │ └── main.go
│ ├── timeout1
│ │ └── main.go
│ ├── timeout2
│ │ └── main.go
│ └── write
│ │ └── main.go
└── 5.3
│ └── main.go
├── ch06
├── .DS_Store
├── 6.2
│ ├── cpu.svg
│ ├── cpu_profile.prof
│ ├── mem.png
│ ├── mem.svg
│ ├── mem_profile1.prof
│ ├── mem_profile2.prof
│ ├── mem_profile3.prof
│ ├── mem_profile4.prof
│ └── profile.go
└── 6.3
│ ├── bhmark
│ ├── bhmark
│ ├── testBenchmark.go
│ └── testBenchmark_test.go
│ ├── example
│ ├── exam_test.go
│ └── testExam.go
│ └── test
│ ├── testTest.go
│ └── testTest_test.go
├── ch08
├── 8.2
│ ├── RWMutex
│ │ └── rwmutex.go
│ ├── cond
│ │ └── cond.go
│ ├── map
│ │ └── map.go
│ ├── mutex
│ │ └── mutex.go
│ ├── once
│ │ └── once.go
│ └── pool
│ │ └── pool.go
├── 8.3
│ ├── advanced
│ │ └── context.go
│ └── context.go
├── 8.4
│ ├── simple
│ │ └── workpool.go
│ └── workpool.go
└── race
│ └── datarace.go
├── ch09
├── 9.1
│ └── httpDemo.go
├── 9.2
│ └── httprouter.go
├── 9.3
│ ├── tcpClient
│ │ └── tcpClient.go
│ ├── tcpServer
│ │ └── tcpServer.go
│ ├── udpClient
│ │ └── udpClient.go
│ ├── udpServer
│ │ └── udpServer.go
│ └── websocket
│ │ ├── index.html
│ │ └── ws.go
└── 9.4
│ ├── adv
│ └── adv.go
│ ├── basic
│ └── basicmiddle.go
│ └── nomiddle.go
├── ch13
├── 13.2
│ ├── main.go
│ └── protocol
│ │ ├── test.pb.go
│ │ └── test.proto
└── 13.3
│ ├── grpc
│ ├── client
│ │ └── client.go
│ ├── protocol
│ │ ├── hello.pb.go
│ │ └── hello.proto
│ └── server
│ │ └── server.go
│ └── rpc
│ ├── client
│ └── client.go
│ └── server
│ └── server.go
├── chapter0
└── sample.go
└── chapter01
├── 1.1
├── helloserver
│ └── main.go
└── helloworld
│ ├── hello
│ └── hello.go
├── 1.2
├── iota
│ └── main.go
├── pointer
│ └── main.go
└── var
│ └── main.go
└── 1.4
└── loop.go
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/.DS_Store
--------------------------------------------------------------------------------
/.idea/book.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # book
2 | 本仓库是本人的出版书籍《Go微服务实战》的配套示例代码。
3 | 读者在使用过程中有任何问题可以提出issue,便于在加印时修正。
4 |
5 | 感谢读者的支持!
6 |
--------------------------------------------------------------------------------
/ch03/3.1/array/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | a := [...]int{1,2,3,4}
7 | b := &a
8 | fmt.Println(a[0],a[1])
9 | fmt.Println(b[0],b[1])
10 | var s = [...]string{"hello","世界"}
11 | for i,v := range s {
12 | fmt.Printf("s[%d]:%s\n",i,v)
13 | }
14 | for i:=0;i
2 |
4 |
6 |
7 |
1155 |
--------------------------------------------------------------------------------
/ch06/6.2/cpu_profile.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/cpu_profile.prof
--------------------------------------------------------------------------------
/ch06/6.2/mem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/mem.png
--------------------------------------------------------------------------------
/ch06/6.2/mem.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
397 |
--------------------------------------------------------------------------------
/ch06/6.2/mem_profile1.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/mem_profile1.prof
--------------------------------------------------------------------------------
/ch06/6.2/mem_profile2.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/mem_profile2.prof
--------------------------------------------------------------------------------
/ch06/6.2/mem_profile3.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/mem_profile3.prof
--------------------------------------------------------------------------------
/ch06/6.2/mem_profile4.prof:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.2/mem_profile4.prof
--------------------------------------------------------------------------------
/ch06/6.2/profile.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 | "runtime"
7 | "runtime/pprof"
8 | "time"
9 | )
10 |
11 | var ch4cpu chan uint64
12 | var chTimer chan struct{}
13 | var memMap map[int]interface{}
14 |
15 | func init(){
16 | ch4cpu = make(chan uint64, 10000)
17 | chTimer = make(chan struct{}, 20)
18 | memMap = make (map[int]interface{})
19 | }
20 | func main() {
21 | c, err := os.Create("/Users/liujinliang/projects/go/src/ljl/book/ch06/6.2/cpu_profile.prof")
22 | if err != nil {
23 | log.Fatal(err)
24 | }
25 |
26 | defer c.Close()
27 |
28 | m1, err := os.Create("/Users/liujinliang/projects/go/src/ljl/book/ch06/6.2/mem_profile1.prof")
29 | if err != nil {
30 | log.Fatal(err)
31 | }
32 |
33 | m2, err := os.Create("/Users/liujinliang/projects/go/src/ljl/book/ch06/6.2/mem_profile2.prof")
34 | if err != nil {
35 | log.Fatal(err)
36 | }
37 |
38 | m3, err := os.Create("/Users/liujinliang/projects/go/src/ljl/book/ch06/6.2/mem_profile3.prof")
39 | if err != nil {
40 | log.Fatal(err)
41 | }
42 |
43 | m4, err := os.Create("/Users/liujinliang/projects/go/src/ljl/book/ch06/6.2/mem_profile4.prof")
44 | if err != nil {
45 | log.Fatal(err)
46 | }
47 |
48 | defer m1.Close()
49 | defer m2.Close()
50 | defer m3.Close()
51 | defer m4.Close()
52 |
53 | pprof.StartCPUProfile(c)
54 | defer pprof.StopCPUProfile()
55 |
56 | memMap[1]= runMEMTest()
57 |
58 | runtime.GC()
59 | pprof.Lookup("heap").WriteTo(m1, 0)
60 | //从此处开始ch4cpu通道被不断的写入数据
61 | go runcputest()
62 | //goroutine运行15秒后chTimer写入值
63 | go func(){
64 | time.Sleep(15 * time.Second)
65 | log.Println("write timer")
66 | chTimer <- struct{}{}
67 |
68 | }()
69 | memMap[2]= runMEMTest()
70 | runtime.GC()
71 | pprof.Lookup("heap").WriteTo(m2, 0)
72 |
73 | memMap[2] = nil
74 | runtime.GC()
75 | pprof.Lookup("heap").WriteTo(m3, 0)
76 |
77 | memMap[1] = nil
78 | runtime.GC()
79 | pprof.Lookup("heap").WriteTo(m4, 0)
80 |
81 | procmsg()
82 | }
83 |
84 | func runMEMTest()([]int) {
85 | mem := make([]int, 100000, 120000)
86 | return mem
87 | }
88 |
89 | func runcputest(){
90 | var i uint64
91 | for {
92 | ch4cpu <- i
93 | i++
94 | }
95 | }
96 |
97 | func procmsg(){
98 | for {
99 | select {
100 | case _ = <-ch4cpu:
101 | case _ = <-chTimer://直到满足此条件for循环才结束
102 | log.Println("timeout")
103 | return
104 | }
105 | }
106 | }
--------------------------------------------------------------------------------
/ch06/6.3/bhmark/bhmark:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/ch06/6.3/bhmark/bhmark
--------------------------------------------------------------------------------
/ch06/6.3/bhmark/testBenchmark.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func fb1(n int) int {
6 | if n == 0 {
7 | return 0
8 | }else if n == 1 {
9 | return 1
10 | }else {
11 | return fb1(n-1) + fb1(n-2)
12 | }
13 |
14 | }
15 |
16 | func fb2(n int) int {
17 | if n == 0 || n == 1 {
18 | return n
19 | }
20 | return fb2(n-1) + fb2(n-2)
21 | }
22 |
23 | func fb3(n int) int {
24 | fbMap := make(map[int]int)
25 | for i := 0;i <= n;i++ {
26 | var t int
27 | if i <= 1 {
28 | t = i
29 | }else {
30 | t = fbMap[i-1] + fbMap[i-2]
31 | }
32 | fbMap[i] = t
33 | }
34 | return fbMap[n]
35 | }
36 |
37 | func main() {
38 | fmt.Println(fb1(50))
39 | fmt.Println(fb2(50))
40 | fmt.Println(fb3(50))
41 | }
42 |
--------------------------------------------------------------------------------
/ch06/6.3/bhmark/testBenchmark_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "testing"
4 |
5 | var final int
6 | func benchmarkfb1(b *testing.B,n int) {
7 | var end int
8 | for i := 0; i < b.N; i++ {
9 | end = fb1(n)
10 | }
11 | final = end
12 | }
13 |
14 | func Benchmarkfb2(b *testing.B,n int) {
15 | var end int
16 | for i := 0; i < b.N; i++ {
17 | end = fb2(n)
18 | }
19 | final = end
20 | }
21 |
22 | func Benchmarkfb3(b *testing.B,n int) {
23 | var end int
24 | for i := 0; i < b.N; i++ {
25 | end = fb3(n)
26 | }
27 | final = end
28 | }
29 |
30 | func Benchmark50fb1(b *testing.B) {
31 | benchmarkfb1(b,30)
32 | }
33 |
34 | func Benchmark50fb2(b *testing.B) {
35 | Benchmarkfb2(b,30)
36 | }
37 |
38 | func Benchmark50fb3(b *testing.B) {
39 | Benchmarkfb3(b,30)
40 | }
--------------------------------------------------------------------------------
/ch06/6.3/example/exam_test.go:
--------------------------------------------------------------------------------
1 | package exam
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func ExampleSum() {
8 | fmt.Println(Sum(1,2))
9 | // Output:
10 | // 3
11 | }
12 |
--------------------------------------------------------------------------------
/ch06/6.3/example/testExam.go:
--------------------------------------------------------------------------------
1 | package exam
2 |
3 | func Sum(a,b int) int {
4 | return a+b
5 | }
6 |
--------------------------------------------------------------------------------
/ch06/6.3/test/testTest.go:
--------------------------------------------------------------------------------
1 | package testTest
2 |
3 | func fb1(n int) int {
4 | if n == 0 {
5 | return 0
6 | }
7 | if n == 1 {
8 | return 1
9 | }
10 | return fb1(n-1) + fb1(n-2)
11 | }
12 |
13 | func fb2(n int) int {
14 | if n == 0 {
15 | return 0
16 | }
17 | if n == 1 {
18 | return 2
19 | }
20 | return fb2(n-1) + fb2(n-2)
21 | }
22 |
--------------------------------------------------------------------------------
/ch06/6.3/test/testTest_test.go:
--------------------------------------------------------------------------------
1 | package testTest
2 |
3 | import "testing"
4 |
5 | func TestFb1(t *testing.T) {
6 | if fb1(0) != 0 {
7 | t.Error(`fb1(0)!=0`)
8 | }
9 | if fb1(1) != 1 {
10 | t.Error(`fb1(1)!=1`)
11 | }
12 | if fb1(2) != 1 {
13 | t.Error(`fb1(2)!=1`)
14 | }
15 | if fb1(10) != 55 {
16 | t.Error(`fb1(10)!=55`)
17 | }
18 | }
19 |
20 | func TestFb2(t *testing.T) {
21 | if fb2(0) != 0 {
22 | t.Error(`fb2(0)!=0`)
23 | }
24 | if fb2(1) != 1 {
25 | t.Error(`fb2(1)!=1`)
26 | }
27 | if fb2(2) != 1 {
28 | t.Error(`fb2(2)!=1`)
29 | }
30 | if fb2(10) != 55 {
31 | t.Error(`fb2(10)!=55`)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ch08/8.2/RWMutex/rwmutex.go:
--------------------------------------------------------------------------------
1 | package rwmutex
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | type pass struct {
10 | RWM sync.RWMutex
11 | pwd string
12 | }
13 | var RoomPass = pass{pwd:"initPass"}
14 |
15 | func Change(p *pass,pwd string) {
16 | p.RWM.Lock()
17 | fmt.Println()
18 | time.Sleep(5*time.Second)
19 | p.pwd = pwd
20 | p.RWM.Unlock()
21 | }
22 |
23 | func getPWD(p *pass) string {
24 | p.RWM.RLock()
25 | fmt.Println("read pwd")
26 | time.Sleep(time.Second)
27 | defer p.RWM.RUnlock()
28 | return p.pwd
29 | }
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ch08/8.2/cond/cond.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | var (
10 | ready = false
11 | singerNum = 3
12 | )
13 |
14 | func Sing(singerId int,c *sync.Cond) {
15 | fmt.Printf("Singer (%d) is ready\n",singerId)
16 | c.L.Lock()
17 | for !ready {
18 | fmt.Printf("Singer (%d) is waiting\n",singerId)
19 | c.Wait()
20 | }
21 | fmt.Printf("Singer (%d) sing a song\n",singerId)
22 | ready = false
23 | c.L.Unlock()
24 | }
25 |
26 | func main() {
27 | cond := sync.NewCond(&sync.Mutex{})
28 | for i:=0;i %d", Read())
39 | }(i)
40 | }
41 |
42 | wg.Wait()
43 | }
44 |
--------------------------------------------------------------------------------
/ch08/8.2/once/once.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | func main() {
9 | var wg sync.WaitGroup
10 | var once sync.Once
11 | for i:=0;i<10;i++{
12 | wg.Add(1)
13 | go func() {
14 | defer wg.Done()
15 | once.Do(onlyOnce)
16 | }()
17 | }
18 | wg.Wait()
19 | }
20 |
21 | func onlyOnce() {
22 | fmt.Println("only once")
23 | }
24 |
--------------------------------------------------------------------------------
/ch08/8.2/pool/pool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | "time"
7 | )
8 |
9 | var byteSlicePool = sync.Pool{
10 | New: func() interface{} {
11 | b := make([]byte,1024)
12 | return &b
13 | },
14 | }
15 |
16 | func main() {
17 | t1 := time.Now().Unix()
18 | //不使用Pool
19 | for i:=0;i<10000000000;i++{
20 | bytes := make([]byte,1024)
21 | _ = bytes
22 | }
23 | t2 := time.Now().Unix()
24 | //使用Pool
25 | for i:=0;i<10000000000;i++{
26 | bytes := byteSlicePool.Get().(*[]byte)
27 | _ = bytes
28 | byteSlicePool.Put(bytes)
29 | }
30 | t3 := time.Now().Unix()
31 | fmt.Printf("不使用Pool:%d s\n",t2-t1)
32 | fmt.Printf("使用Pool:%d s\n",t3-t2)
33 | }
34 |
--------------------------------------------------------------------------------
/ch08/8.3/advanced/context.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io/ioutil"
7 | "net/http"
8 | "sync"
9 | "time"
10 | )
11 |
12 | var (
13 | url string
14 | t = 5
15 | wg sync.WaitGroup
16 | )
17 |
18 | type information struct {
19 | r *http.Response
20 | err error
21 | }
22 |
23 | func connect(c context.Context) error {
24 | defer wg.Done()
25 | info := make(chan information,1)
26 | tr := &http.Transport{}
27 | httpClient := &http.Client{Transport:tr}
28 | req,_ := http.NewRequest("GET",url,nil)
29 | req = req.WithContext(c)
30 |
31 | go func() {
32 | res,err := httpClient.Do(req)
33 | if err != nil {
34 | fmt.Println(err)
35 | info <- information{nil,err}
36 | return
37 | }else{
38 | info <- information{res,err}
39 | }
40 | }()
41 |
42 | select {
43 | case <- c.Done():
44 | fmt.Println("request is cancelled!!")
45 | case ok := <-info:
46 | err := ok.err
47 | r := ok.r
48 | if err != nil {
49 | fmt.Println("ERROR:",err)
50 | return err
51 | }
52 | defer r.Body.Close()
53 | realInfo,err := ioutil.ReadAll(r.Body)
54 | if err != nil {
55 | fmt.Println("ERROR:",err)
56 | return err
57 | }
58 | fmt.Printf("Response:%s\n",realInfo)
59 | }
60 | return nil
61 | }
62 |
63 | func main() {
64 | url = "http://google.com" //试着换成baidu
65 | ctx := context.Background()
66 | ctx,cancel := context.WithTimeout(ctx,time.Duration(t)*time.Second)
67 | defer cancel()
68 | fmt.Printf("connecting to %s \n",url)
69 | wg.Add(1)
70 | go connect(ctx)
71 | wg.Wait()
72 | fmt.Println("END...")
73 | }
74 |
--------------------------------------------------------------------------------
/ch08/8.3/context.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func testWCancel(t int) {
10 | ctx := context.Background()
11 | ctx,cancel := context.WithCancel(ctx)
12 | defer cancel()
13 | go func() {
14 | time.Sleep(3*time.Second)
15 | cancel()
16 | }()
17 | select {
18 | case <- ctx.Done():
19 | fmt.Println("testWCancel.Done:",ctx.Err())
20 | case e := <- time.After(time.Duration(t)*time.Second):
21 | fmt.Println("testWCancel:",e)
22 | }
23 | return
24 | }
25 |
26 | func testWDeadline(t int) {
27 | ctx := context.Background()
28 | dl := time.Now().Add(time.Duration(1*t)*time.Second)
29 | ctx,cancel := context.WithDeadline(ctx,dl)
30 | defer cancel()
31 | go func() {
32 | time.Sleep(3*time.Second)
33 | cancel()
34 | }()
35 | select {
36 | case <- ctx.Done():
37 | fmt.Println("testWDeadline.Done:",ctx.Err())
38 | case e := <-time.After(time.Duration(t)*time.Second):
39 | fmt.Println("testWDeadline:",e)
40 | }
41 | return
42 | }
43 |
44 | func testWTimeout(t int) {
45 | ctx := context.Background()
46 | ctx,cancel := context.WithTimeout(ctx,time.Duration(t)*time.Second)
47 | defer cancel()
48 |
49 | go func() {
50 | time.Sleep(3*time.Second)
51 | cancel()
52 | }()
53 | select {
54 | case <- ctx.Done():
55 | fmt.Println("testWTimeout.Done:",ctx.Err())
56 | case e := <-time.After(time.Duration(t)*time.Second):
57 | fmt.Println("testWTimeout:",e)
58 | }
59 | return
60 | }
61 |
62 | func main() {
63 | var t = 4
64 | testWCancel(t)
65 | testWDeadline(t)
66 | testWTimeout(t)
67 | }
68 |
--------------------------------------------------------------------------------
/ch08/8.4/simple/workpool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 | )
7 |
8 | func worcker(id int,jobs <- chan int,results chan <- int) {
9 | for job := range jobs {
10 | fmt.Printf("worker(%d) start to do job(%d)\n",id,job)
11 | time.Sleep(time.Second)
12 | fmt.Printf("worker(%d) finished job(%d)\n",id,job)
13 | results <- job*job
14 | }
15 | }
16 |
17 | func main() {
18 | jobs := make(chan int,100)
19 | resultes := make(chan int,100)
20 |
21 | for id := 0;id<3;id++{
22 | go worcker(id,jobs,resultes)
23 | }
24 | for job:=1;job<=5;job++{
25 | jobs <- job
26 | }
27 | close(jobs)
28 |
29 | for i:=1;i<=5;i++{
30 | <-resultes
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ch08/8.4/workpool.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "reflect"
6 | "time"
7 | )
8 |
9 | type Task struct {
10 | Num int
11 | }
12 |
13 | type Job struct {
14 | Task Task
15 | }
16 | var (
17 | MaxWorker = 5
18 | JobQueue chan Job //工作通道,模拟需要处理的所有工作
19 | )
20 |
21 | type Worker struct {
22 | id int //id
23 | WorkerPool chan chan Job //工作者池(通道的通道),每个元素是一个job通道,公共的job
24 | JobChannel chan Job //工作通道,每个元素是一个job,worker私有的job
25 | exit chan bool //结束信号
26 | }
27 |
28 | func NewWorker(workerPool chan chan Job, id int) Worker {
29 | fmt.Printf("new a worker(%d)\n",id)
30 | return Worker{
31 | id: id,
32 | WorkerPool: workerPool, //workerPool和scheduler的是同一个
33 | JobChannel: make(chan Job),
34 | exit: make(chan bool),
35 | }
36 | }
37 |
38 | //监听任务和结束信号
39 | func (w Worker) Start() {
40 | go func() {
41 | for {
42 | // 将当前的任务队列注册到工作池.
43 | w.WorkerPool <- w.JobChannel
44 | fmt.Println("register private JobChannel to public WorkerPool", w)
45 | select {
46 | case job := <-w.JobChannel://收到任务
47 | fmt.Println("get a job from private w.JobChannel")
48 | fmt.Println(job)
49 | time.Sleep(5* time.Second)
50 | case <-w.exit://收到结束信号
51 | fmt.Println("worker exit",w)
52 | return
53 | }
54 | }
55 | }()
56 | }
57 |
58 | func (w Worker) Stop() {
59 | go func() {
60 | w.exit <- true
61 | }()
62 | }
63 |
64 | //排程中心
65 | type Scheduler struct {
66 | WorkerPool chan chan Job //工作池
67 | MaxWorkers int //最大工作者数
68 | Workers []*Worker //worker队列
69 | }
70 |
71 | //创建排程中心
72 | func NewScheduler(maxWorkers int) *Scheduler {
73 | pool := make(chan chan Job, maxWorkers) //工作池
74 | return &Scheduler{WorkerPool: pool, MaxWorkers: maxWorkers}
75 | }
76 |
77 | //工作池的初始化
78 | func (s *Scheduler) Create() {
79 | workers := make([]*Worker,s.MaxWorkers)
80 | for i := 0; i < s.MaxWorkers; i++ {
81 | worker := NewWorker(s.WorkerPool, i)
82 | worker.Start()
83 | workers[i] = &worker
84 | }
85 | s.Workers = workers
86 | go s.schedule()
87 | }
88 |
89 | //工作池的关闭
90 | func (s *Scheduler) Shutdown() {
91 | workers := s.Workers
92 | for _,w := range workers{
93 | w.Stop()
94 | }
95 | time.Sleep(time.Second)
96 | close(s.WorkerPool)
97 | }
98 |
99 | //排程
100 | func (s *Scheduler) schedule() {
101 | for {
102 | select {
103 | case job := <-JobQueue:
104 | fmt.Println("get a job from JobQueue")
105 | go func(job Job) {
106 | //从WorkerPool获取jobChannel,忙时阻塞
107 | jobChannel := <-s.WorkerPool
108 | fmt.Println("get a private jobChannel from public s.WorkerPool", reflect.TypeOf(jobChannel))
109 | jobChannel <- job
110 | fmt.Println("worker's private jobChannel add one job")
111 | }(job)
112 | }
113 | }
114 | }
115 |
116 | func main() {
117 | JobQueue = make(chan Job, 5)
118 | scheduler := NewScheduler(MaxWorker)
119 | scheduler.Create()
120 | time.Sleep(1 * time.Second)
121 | go createJobQueue()
122 | time.Sleep(100 * time.Second)
123 | scheduler.Shutdown()
124 | time.Sleep(10*time.Second)
125 | }
126 | //创建模拟任务
127 | func createJobQueue() {
128 | for i := 0; i < 30; i++ {
129 | task := Task{Num: 1}
130 | job := Job{Task: task}
131 | JobQueue <- job
132 | fmt.Println("JobQueue add one job")
133 | time.Sleep(1 * time.Second)
134 | }
135 |
136 | }
--------------------------------------------------------------------------------
/ch08/race/datarace.go:
--------------------------------------------------------------------------------
1 | package singlegoroutine
2 |
3 | var realNum = make(chan int)//设置数字值
4 | var delta = make(chan int)//设置设置的增减额
5 |
6 | func SetNumber(n int) {
7 | realNum <- n
8 | }
9 | func ChangeByDelta(d int) {
10 | delta <- d
11 | }
12 | func GetNumber() int{
13 | return <- realNum
14 | }
15 | func moitor() {
16 | var i int //把数值限定在方法内,goroutine运行后仅在goroutine内
17 | for {
18 | select{
19 | case i = <- realNum:
20 | case d := <- delta:
21 | i += d
22 | case realNum <- i:
23 | }
24 | }
25 | }
26 | func init() {
27 | go moitor()
28 | }
--------------------------------------------------------------------------------
/ch09/9.1/httpDemo.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "net/http"
4 |
5 | func main() {
6 | http.Handle("/", &ThisHandler{})
7 | http.Handle("/hello", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
8 | w.Write([]byte("Hello!!"))
9 | }))
10 | http.HandleFunc("/hi", sayHi)
11 |
12 | http.ListenAndServe(":8080", nil)
13 | }
14 |
15 | func sayHi(w http.ResponseWriter, r *http.Request) {
16 | w.Write([]byte("Hi!!"))
17 | }
18 |
19 | type ThisHandler struct{}
20 |
21 | func (m *ThisHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
22 | w.Write([]byte("ThisHandler's ServeHTTP"))
23 | }
--------------------------------------------------------------------------------
/ch09/9.2/httprouter.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "github.com/julienschmidt/httprouter"
6 | "log"
7 | "net/http"
8 | )
9 |
10 | func Home(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
11 | fmt.Fprint(w, "Welcome back to home!\n")
12 | }
13 |
14 | func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
15 | fmt.Fprintf(w, "Hello, %s!\n", ps.ByName("name"))
16 | }
17 |
18 | func main() {
19 | router := httprouter.New()
20 | router.GET("/", Home)
21 | router.GET("/hello/:name", Hello)
22 |
23 | log.Fatal(http.ListenAndServe(":8081", router))
24 | }
--------------------------------------------------------------------------------
/ch09/9.3/tcpClient/tcpClient.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "io/ioutil"
6 | "net"
7 | "os"
8 | )
9 |
10 | func main() {
11 | addr := "www.baidu.com:80"
12 | tcpAddr,err := net.ResolveTCPAddr("tcp",addr)
13 | if err != nil {
14 | fmt.Println("Error:",err.Error())
15 | return
16 | }
17 |
18 | myConn,err := net.DialTCP("tcp",nil,tcpAddr)
19 | if err != nil {
20 | fmt.Println("Error:",err.Error())
21 | return
22 | }
23 |
24 | _,err = myConn.Write([]byte("HEAD / HTTP/1.1\r\n\r\n"))
25 |
26 | result,err := ioutil.ReadAll(myConn)
27 | if err != nil {
28 | fmt.Println("Error:",err.Error())
29 | return
30 | }
31 | fmt.Println(string(result))
32 | os.Exit(0)
33 | }
34 |
--------------------------------------------------------------------------------
/ch09/9.3/tcpServer/tcpServer.go:
--------------------------------------------------------------------------------
1 |
2 | package main
3 |
4 | import (
5 | "fmt"
6 | "net"
7 | "os"
8 | "time"
9 | )
10 |
11 | func checkError(err error) {
12 | if err != nil {
13 | fmt.Println("Fatal error :", err.Error())
14 | os.Exit(1)
15 | }
16 | }
17 |
18 | func nowtime() string {
19 | return time.Now().String()
20 | }
21 |
22 | func main() {
23 | addr := ":7777"
24 | tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
25 | checkError(err)
26 |
27 | mylistener, err := net.ListenTCP("tcp", tcpAddr)
28 | checkError(err)
29 | i := 0
30 | for {
31 | myconn, err := mylistener.Accept()
32 | fmt.Printf("myconn ")
33 | if err != nil {
34 | continue
35 | }
36 | i++
37 |
38 | nowTime := nowtime()
39 | fmt.Printf("request no %d return time:%s \n",i,nowTime)
40 | myconn.Write([]byte(nowTime))
41 | myconn.Close()
42 |
43 | }
44 | }
--------------------------------------------------------------------------------
/ch09/9.3/udpClient/udpClient.go:
--------------------------------------------------------------------------------
1 | package main
2 | import (
3 | "bufio"
4 | "fmt"
5 | "net"
6 | )
7 |
8 | func main() {
9 | p := make([]byte, 512)
10 | conn, err := net.Dial("udp", "127.0.0.1:7778")
11 | defer conn.Close()
12 | if err != nil {
13 | fmt.Printf("Some error %v", err)
14 | return
15 | }
16 | fmt.Fprintf(conn, "Hi UDP Server, How are you? \n")
17 | n, err := bufio.NewReader(conn).Read(p)
18 | if err == nil {
19 | fmt.Printf("Response:%s\n", p[0:n])
20 | } else {
21 | fmt.Printf("Error: %v\n", err)
22 | }
23 | }
--------------------------------------------------------------------------------
/ch09/9.3/udpServer/udpServer.go:
--------------------------------------------------------------------------------
1 | package main
2 | import (
3 | "fmt"
4 | "net"
5 | )
6 |
7 | func sendResponse(conn *net.UDPConn, addr *net.UDPAddr) {
8 | _,err := conn.WriteToUDP([]byte("From server: Hello, I got your mesage "), addr)
9 | if err != nil {
10 | fmt.Printf("Couldn't send response %v", err)
11 | }
12 | }
13 |
14 |
15 | func main() {
16 | p := make([]byte, 512)
17 | addr := net.UDPAddr{
18 | Port: 7778,
19 | IP: net.ParseIP("127.0.0.1"),
20 | }
21 | ser, err := net.ListenUDP("udp", &addr)
22 | if err != nil {
23 | fmt.Printf("Some error %v\n", err)
24 | return
25 | }
26 | for {
27 | n,remoteaddr,err := ser.ReadFromUDP(p)
28 | fmt.Printf("Read a message from %v : %s \n", remoteaddr, p[0:n])
29 | if err != nil {
30 | fmt.Printf("Error: %v", err)
31 | continue
32 | }
33 | go sendResponse(ser, remoteaddr)
34 | }
35 | }
--------------------------------------------------------------------------------
/ch09/9.3/websocket/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | chat/history:
6 |
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/ch09/9.3/websocket/ws.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "io/ioutil"
7 | "log"
8 | "net/http"
9 |
10 | "github.com/gorilla/websocket"
11 | )
12 |
13 | // 1
14 | type Message struct {
15 | Name string `json:"name"`
16 | Mess string `json:"mess"`
17 | }
18 |
19 | var clients = make(map[*websocket.Conn]bool)
20 | var broadcast = make(chan *Message)
21 | var upgrader = websocket.Upgrader{
22 | CheckOrigin: func(r *http.Request) bool {
23 | return true
24 | },
25 | }
26 |
27 | func main() {
28 | // 2
29 | http.HandleFunc("/", rootHandler)
30 | http.HandleFunc("/chat", messHandler)
31 | http.HandleFunc("/ws", wsHandler)
32 | go echo()
33 |
34 | panic(http.ListenAndServe(":7778", nil))
35 | }
36 |
37 | func rootHandler(w http.ResponseWriter, r *http.Request) {
38 | content, err := ioutil.ReadFile("/Users/liujinliang/projects/go/src/ljl/book/ch09/9.3/websocket/index.html")
39 | if err != nil {
40 | fmt.Println("Could not open file.", err)
41 | }
42 | fmt.Fprintf(w, "%s", content)
43 | }
44 |
45 | func writer(mess *Message) {
46 | broadcast <- mess
47 | }
48 |
49 | func messHandler(w http.ResponseWriter, r *http.Request) {
50 | var mess Message
51 | if err := json.NewDecoder(r.Body).Decode(&mess); err != nil {
52 | log.Printf("ERROR: %s", err)
53 | http.Error(w, "Bad request", http.StatusTeapot)
54 | return
55 | }
56 | defer r.Body.Close()
57 | go writer(&mess)
58 | }
59 |
60 | func wsHandler(w http.ResponseWriter, r *http.Request) {
61 | ws, err := upgrader.Upgrade(w, r, nil)
62 | if err != nil {
63 | log.Fatal(err)
64 | }
65 |
66 | // register client
67 | clients[ws] = true
68 | }
69 |
70 | // 3
71 | func echo() {
72 | for {
73 | mess := <-broadcast
74 | hisMess := fmt.Sprintf("%s : %s \n", mess.Name, mess.Mess)
75 | fmt.Println(hisMess)
76 | // send to every client that is currently connected
77 | for client := range clients {
78 | err := client.WriteMessage(websocket.TextMessage, []byte(hisMess))
79 | if err != nil {
80 | log.Printf("Websocket error: %s", err)
81 | client.Close()
82 | delete(clients, client)
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/ch09/9.4/adv/adv.go:
--------------------------------------------------------------------------------
1 | package adv
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "log"
7 | "net/http"
8 | "time"
9 | )
10 |
11 | type Middleware func(http.HandlerFunc) http.HandlerFunc
12 |
13 | //Get user's auth code
14 | func GetAuthCode() Middleware {
15 | // Create a new Middleware
16 | return func(f http.HandlerFunc) http.HandlerFunc {
17 | //Define the http.HandlerFunc
18 | return func(w http.ResponseWriter, r *http.Request) {
19 | code := 0
20 | //auth code is available only when access root
21 | if r.URL.Path != "/"{
22 | code = -1
23 | }
24 | //create a new request context containing the auth code, context available >= go 1.7
25 | ctxWithUser := context.WithValue(r.Context(), code, "User")
26 | //create a new request using that new context
27 | rWithUser := r.WithContext(ctxWithUser)
28 | //call the real handler, passing the new request
29 | f(w,rWithUser)
30 | }
31 | }
32 | }
33 |
34 | // Ensure user's auth
35 | func EnsureAuth() Middleware {
36 | // Create a new Middleware
37 | return func(f http.HandlerFunc) http.HandlerFunc {
38 | //Define the http.HandlerFunc
39 | return func(w http.ResponseWriter, r *http.Request) {
40 | user := r.Context().Value(0)
41 | if user != nil {
42 | log.Println("auth available!")
43 | }else {
44 | http.Error(w,"Please sign in!",http.StatusUnauthorized)
45 | return
46 | }
47 | // Call the next middleware/handler in chain
48 | f(w,r)
49 | }
50 | }
51 | }
52 | // Logging logs all requests with its path and the time it took to process
53 | func Logging() Middleware {
54 | return func(f http.HandlerFunc) http.HandlerFunc {
55 | return func(w http.ResponseWriter, r *http.Request) {
56 | // Do middleware things
57 | start := time.Now()
58 | defer func() { log.Println(r.URL.Path, time.Since(start)) }()
59 | // Call the next middleware/handler in chain
60 | f(w, r)
61 | }
62 | }
63 | }
64 |
65 | // Method ensures that url can only be requested with a specific method, else returns a 400 Bad Request
66 | func Method(m string) Middleware {
67 | // Create a new Middleware
68 | return func(f http.HandlerFunc) http.HandlerFunc {
69 | // Define the http.HandlerFunc
70 | return func(w http.ResponseWriter, r *http.Request) {
71 |
72 | // Do middleware things
73 | if r.Method != m {
74 | http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
75 | return
76 | }else {
77 | log.Println("request is :",m)
78 | }
79 | // Call the next middleware/handler in chain
80 | f(w, r)
81 | }
82 | }
83 | }
84 |
85 | // Chain applies middlewares to a http.HandlerFunc
86 | func Chain(f http.HandlerFunc, middlewares ...Middleware) http.HandlerFunc {
87 | for _, m := range middlewares {
88 | f = m(f)
89 | }
90 | return f
91 | }
92 |
93 | func Hello(w http.ResponseWriter, r *http.Request) {
94 | fmt.Fprintln(w, "hello world")
95 | }
96 | func Auth(w http.ResponseWriter, r *http.Request) {
97 | fmt.Fprintln(w,"You r authorized!")
98 | }
99 |
100 | func main() {
101 | http.HandleFunc("/", Chain(Hello, Method("GET"),GetAuthCode(), Logging()))
102 | http.HandleFunc("/auth/", Chain(Auth, Method("GET"),GetAuthCode(),EnsureAuth(), Logging()))
103 | http.ListenAndServe(":7775", nil)
104 | }
--------------------------------------------------------------------------------
/ch09/9.4/basic/basicmiddle.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | "time"
8 | )
9 | type Logger struct { //Logger is a middleware handler
10 | handler http.Handler
11 | }
12 |
13 | func (l *Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
14 | start := time.Now()
15 | l.handler.ServeHTTP(w,r)
16 | log.Printf("%s %s %v",r.Method,r.URL.Path,time.Since(start))
17 | }
18 |
19 | func NewLogger(handlerToWrap http.Handler) *Logger {
20 | return &Logger{handlerToWrap}
21 | }
22 |
23 | func HelloHandler(w http.ResponseWriter, r *http.Request) {
24 | w.Write([]byte("Hello,World!"))
25 | }
26 | func CurrentTimeHandler(w http.ResponseWriter, r *http.Request) {
27 | curTime := time.Now().Format(time.Kitchen)
28 | w.Write([]byte(fmt.Sprintf("Current time is %v",curTime)))
29 | }
30 | func main() {
31 | mux := http.NewServeMux()
32 | mux.HandleFunc("/v1/hello",HelloHandler)
33 | mux.HandleFunc("/v1/time",CurrentTimeHandler)
34 | wrappedMux := NewLogger(mux) //包装了中间件的mux
35 | addr := "localhost:7774"
36 | log.Printf("listen at:%s",addr)
37 | log.Fatal(http.ListenAndServe(addr,wrappedMux))
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/ch09/9.4/nomiddle.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | "time"
8 | )
9 |
10 | func HelloHandler(w http.ResponseWriter, r *http.Request) {
11 | w.Write([]byte("Hello,World!"))
12 | }
13 |
14 | func CurrentTimeHandler(w http.ResponseWriter, r *http.Request) {
15 | curTime := time.Now().Format(time.Kitchen)
16 | w.Write([]byte(fmt.Sprintf("Current time is %v",curTime)))
17 | }
18 |
19 | func main() {
20 | mux := http.NewServeMux()
21 | mux.HandleFunc("/v1/hello",HelloHandler)
22 | mux.HandleFunc("/v1/time",CurrentTimeHandler)
23 | addr := "localhost:7774"
24 | log.Printf("listen at:%s",addr)
25 | log.Fatal(http.ListenAndServe(addr,mux))
26 | }
27 |
--------------------------------------------------------------------------------
/ch13/13.2/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "./protocol"
5 | "github.com/gogo/protobuf/proto"
6 | "log"
7 | )
8 |
9 | func main() {
10 | u := &protocol.UserInfo{
11 | Message: *proto.String("testInfo"),
12 | Length: *proto.Int32(10),
13 | }
14 |
15 | data,err := proto.Marshal(u)
16 | if err != nil {
17 | log.Fatal("marshaling error: ", err)
18 | }
19 | newInfo := &protocol.UserInfo{}
20 | err = proto.Unmarshal(data,newInfo)
21 | if err != nil {
22 | log.Fatal("unmarshaling error: ", err)
23 | }
24 |
25 | log.Println(newInfo.GetMessage())
26 | }
--------------------------------------------------------------------------------
/ch13/13.2/protocol/test.pb.go:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-go. DO NOT EDIT.
2 | // source: test.proto
3 |
4 | package protocol
5 |
6 | import (
7 | fmt "fmt"
8 | proto "github.com/golang/protobuf/proto"
9 | math "math"
10 | )
11 |
12 | // Reference imports to suppress errors if they are not otherwise used.
13 | var _ = proto.Marshal
14 | var _ = fmt.Errorf
15 | var _ = math.Inf
16 |
17 | // This is a compile-time assertion to ensure that this generated file
18 | // is compatible with the proto package it is being compiled against.
19 | // A compilation error at this line likely means your copy of the
20 | // proto package needs to be updated.
21 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
22 |
23 | type FOO int32
24 |
25 | const (
26 | FOO_X FOO = 0
27 | )
28 |
29 | var FOO_name = map[int32]string{
30 | 0: "X",
31 | }
32 |
33 | var FOO_value = map[string]int32{
34 | "X": 0,
35 | }
36 |
37 | func (x FOO) String() string {
38 | return proto.EnumName(FOO_name, int32(x))
39 | }
40 |
41 | func (FOO) EnumDescriptor() ([]byte, []int) {
42 | return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
43 | }
44 |
45 | //message是固定关键字。UserInfo是自定义类名
46 | type UserInfo struct {
47 | Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
48 | Length int32 `protobuf:"varint,2,opt,name=length,proto3" json:"length,omitempty"`
49 | XXX_NoUnkeyedLiteral struct{} `json:"-"`
50 | XXX_unrecognized []byte `json:"-"`
51 | XXX_sizecache int32 `json:"-"`
52 | }
53 |
54 | func (m *UserInfo) Reset() { *m = UserInfo{} }
55 | func (m *UserInfo) String() string { return proto.CompactTextString(m) }
56 | func (*UserInfo) ProtoMessage() {}
57 | func (*UserInfo) Descriptor() ([]byte, []int) {
58 | return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
59 | }
60 |
61 | func (m *UserInfo) XXX_Unmarshal(b []byte) error {
62 | return xxx_messageInfo_UserInfo.Unmarshal(m, b)
63 | }
64 | func (m *UserInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
65 | return xxx_messageInfo_UserInfo.Marshal(b, m, deterministic)
66 | }
67 | func (m *UserInfo) XXX_Merge(src proto.Message) {
68 | xxx_messageInfo_UserInfo.Merge(m, src)
69 | }
70 | func (m *UserInfo) XXX_Size() int {
71 | return xxx_messageInfo_UserInfo.Size(m)
72 | }
73 | func (m *UserInfo) XXX_DiscardUnknown() {
74 | xxx_messageInfo_UserInfo.DiscardUnknown(m)
75 | }
76 |
77 | var xxx_messageInfo_UserInfo proto.InternalMessageInfo
78 |
79 | func (m *UserInfo) GetMessage() string {
80 | if m != nil {
81 | return m.Message
82 | }
83 | return ""
84 | }
85 |
86 | func (m *UserInfo) GetLength() int32 {
87 | if m != nil {
88 | return m.Length
89 | }
90 | return 0
91 | }
92 |
93 | func init() {
94 | proto.RegisterEnum("protocol.FOO", FOO_name, FOO_value)
95 | proto.RegisterType((*UserInfo)(nil), "protocol.UserInfo")
96 | }
97 |
98 | func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) }
99 |
100 | var fileDescriptor_c161fcfdc0c3ff1e = []byte{
101 | // 112 bytes of a gzipped FileDescriptorProto
102 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x49, 0x2d, 0x2e,
103 | 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x00, 0x53, 0xc9, 0xf9, 0x39, 0x4a, 0x36, 0x5c,
104 | 0x1c, 0xa1, 0xc5, 0xa9, 0x45, 0x9e, 0x79, 0x69, 0xf9, 0x42, 0x12, 0x5c, 0xec, 0xb9, 0xa9, 0xc5,
105 | 0xc5, 0x89, 0xe9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x30, 0xae, 0x90, 0x18, 0x17,
106 | 0x5b, 0x4e, 0x6a, 0x5e, 0x7a, 0x49, 0x86, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x94, 0xa7,
107 | 0xc5, 0xc3, 0xc5, 0xec, 0xe6, 0xef, 0x2f, 0xc4, 0xca, 0xc5, 0x18, 0x21, 0xc0, 0x90, 0xc4, 0x06,
108 | 0x36, 0xd5, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x36, 0x8b, 0xb0, 0x7b, 0x6a, 0x00, 0x00, 0x00,
109 | }
110 |
--------------------------------------------------------------------------------
/ch13/13.2/protocol/test.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3"; //指定版本(proto3、proto2)
2 | package protocol;
3 |
4 | enum FOO
5 | {
6 | X = 0;
7 | };
8 |
9 | //message是固定关键字。UserInfo是自定义类名
10 | message UserInfo{
11 | string message = 1;
12 | int32 length = 2;
13 | }
--------------------------------------------------------------------------------
/ch13/13.3/grpc/client/client.go:
--------------------------------------------------------------------------------
1 | package main
2 | import (
3 | "context"
4 | "fmt"
5 | "google.golang.org/grpc"
6 | pt "../protocol"
7 | )
8 | const (
9 | post = "127.0.0.1:18887"
10 | )
11 | func main() {
12 | // 客户端连接服务器
13 | conn,err:=grpc.Dial(post,grpc.WithInsecure())
14 | if err!=nil {
15 | fmt.Println("连接服务器失败",err)
16 | }
17 |
18 | defer conn.Close()
19 |
20 | //获得grpc句柄
21 | c:=pt.NewHelloServerClient(conn)
22 |
23 | //远程调用 SayHello接口
24 | r1, err := c.SayHello(context.Background(), &pt.HelloRequest{Name: "Scott"})
25 | if err != nil {
26 | fmt.Println("cloud not get Hello server ..", err)
27 | return
28 | }
29 | fmt.Println("HelloServer resp: ", r1.Message)
30 | //远程调用 GetHelloMsg接口
31 | r2, err := c.GetHelloMsg(context.Background(), &pt.HelloRequest{Name: "Scott"})
32 | if err != nil {
33 | fmt.Println("cloud not get hello msg ..", err)
34 | return
35 | }
36 | fmt.Println("HelloServer resp: ", r2.Msg)
37 | }
--------------------------------------------------------------------------------
/ch13/13.3/grpc/protocol/hello.pb.go:
--------------------------------------------------------------------------------
1 | // Code generated by protoc-gen-go. DO NOT EDIT.
2 | // source: hello.proto
3 |
4 | package protocol
5 |
6 | import (
7 | context "context"
8 | fmt "fmt"
9 | proto "github.com/golang/protobuf/proto"
10 | grpc "google.golang.org/grpc"
11 | codes "google.golang.org/grpc/codes"
12 | status "google.golang.org/grpc/status"
13 | math "math"
14 | )
15 |
16 | // Reference imports to suppress errors if they are not otherwise used.
17 | var _ = proto.Marshal
18 | var _ = fmt.Errorf
19 | var _ = math.Inf
20 |
21 | // This is a compile-time assertion to ensure that this generated file
22 | // is compatible with the proto package it is being compiled against.
23 | // A compilation error at this line likely means your copy of the
24 | // proto package needs to be updated.
25 | const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
26 |
27 | type HelloRequest struct {
28 | Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
29 | XXX_NoUnkeyedLiteral struct{} `json:"-"`
30 | XXX_unrecognized []byte `json:"-"`
31 | XXX_sizecache int32 `json:"-"`
32 | }
33 |
34 | func (m *HelloRequest) Reset() { *m = HelloRequest{} }
35 | func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
36 | func (*HelloRequest) ProtoMessage() {}
37 | func (*HelloRequest) Descriptor() ([]byte, []int) {
38 | return fileDescriptor_61ef911816e0a8ce, []int{0}
39 | }
40 |
41 | func (m *HelloRequest) XXX_Unmarshal(b []byte) error {
42 | return xxx_messageInfo_HelloRequest.Unmarshal(m, b)
43 | }
44 | func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
45 | return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic)
46 | }
47 | func (m *HelloRequest) XXX_Merge(src proto.Message) {
48 | xxx_messageInfo_HelloRequest.Merge(m, src)
49 | }
50 | func (m *HelloRequest) XXX_Size() int {
51 | return xxx_messageInfo_HelloRequest.Size(m)
52 | }
53 | func (m *HelloRequest) XXX_DiscardUnknown() {
54 | xxx_messageInfo_HelloRequest.DiscardUnknown(m)
55 | }
56 |
57 | var xxx_messageInfo_HelloRequest proto.InternalMessageInfo
58 |
59 | func (m *HelloRequest) GetName() string {
60 | if m != nil {
61 | return m.Name
62 | }
63 | return ""
64 | }
65 |
66 | type HelloReplay struct {
67 | Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
68 | XXX_NoUnkeyedLiteral struct{} `json:"-"`
69 | XXX_unrecognized []byte `json:"-"`
70 | XXX_sizecache int32 `json:"-"`
71 | }
72 |
73 | func (m *HelloReplay) Reset() { *m = HelloReplay{} }
74 | func (m *HelloReplay) String() string { return proto.CompactTextString(m) }
75 | func (*HelloReplay) ProtoMessage() {}
76 | func (*HelloReplay) Descriptor() ([]byte, []int) {
77 | return fileDescriptor_61ef911816e0a8ce, []int{1}
78 | }
79 |
80 | func (m *HelloReplay) XXX_Unmarshal(b []byte) error {
81 | return xxx_messageInfo_HelloReplay.Unmarshal(m, b)
82 | }
83 | func (m *HelloReplay) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
84 | return xxx_messageInfo_HelloReplay.Marshal(b, m, deterministic)
85 | }
86 | func (m *HelloReplay) XXX_Merge(src proto.Message) {
87 | xxx_messageInfo_HelloReplay.Merge(m, src)
88 | }
89 | func (m *HelloReplay) XXX_Size() int {
90 | return xxx_messageInfo_HelloReplay.Size(m)
91 | }
92 | func (m *HelloReplay) XXX_DiscardUnknown() {
93 | xxx_messageInfo_HelloReplay.DiscardUnknown(m)
94 | }
95 |
96 | var xxx_messageInfo_HelloReplay proto.InternalMessageInfo
97 |
98 | func (m *HelloReplay) GetMessage() string {
99 | if m != nil {
100 | return m.Message
101 | }
102 | return ""
103 | }
104 |
105 | type HelloMessage struct {
106 | Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
107 | XXX_NoUnkeyedLiteral struct{} `json:"-"`
108 | XXX_unrecognized []byte `json:"-"`
109 | XXX_sizecache int32 `json:"-"`
110 | }
111 |
112 | func (m *HelloMessage) Reset() { *m = HelloMessage{} }
113 | func (m *HelloMessage) String() string { return proto.CompactTextString(m) }
114 | func (*HelloMessage) ProtoMessage() {}
115 | func (*HelloMessage) Descriptor() ([]byte, []int) {
116 | return fileDescriptor_61ef911816e0a8ce, []int{2}
117 | }
118 |
119 | func (m *HelloMessage) XXX_Unmarshal(b []byte) error {
120 | return xxx_messageInfo_HelloMessage.Unmarshal(m, b)
121 | }
122 | func (m *HelloMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
123 | return xxx_messageInfo_HelloMessage.Marshal(b, m, deterministic)
124 | }
125 | func (m *HelloMessage) XXX_Merge(src proto.Message) {
126 | xxx_messageInfo_HelloMessage.Merge(m, src)
127 | }
128 | func (m *HelloMessage) XXX_Size() int {
129 | return xxx_messageInfo_HelloMessage.Size(m)
130 | }
131 | func (m *HelloMessage) XXX_DiscardUnknown() {
132 | xxx_messageInfo_HelloMessage.DiscardUnknown(m)
133 | }
134 |
135 | var xxx_messageInfo_HelloMessage proto.InternalMessageInfo
136 |
137 | func (m *HelloMessage) GetMsg() string {
138 | if m != nil {
139 | return m.Msg
140 | }
141 | return ""
142 | }
143 |
144 | func init() {
145 | proto.RegisterType((*HelloRequest)(nil), "protocol.HelloRequest")
146 | proto.RegisterType((*HelloReplay)(nil), "protocol.HelloReplay")
147 | proto.RegisterType((*HelloMessage)(nil), "protocol.HelloMessage")
148 | }
149 |
150 | func init() { proto.RegisterFile("hello.proto", fileDescriptor_61ef911816e0a8ce) }
151 |
152 | var fileDescriptor_61ef911816e0a8ce = []byte{
153 | // 177 bytes of a gzipped FileDescriptorProto
154 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x48, 0xcd, 0xc9,
155 | 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x00, 0x53, 0xc9, 0xf9, 0x39, 0x4a, 0x4a,
156 | 0x5c, 0x3c, 0x1e, 0x20, 0x89, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x21, 0x21, 0x2e, 0x96,
157 | 0xbc, 0xc4, 0xdc, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x30, 0x5b, 0x49, 0x9d, 0x8b,
158 | 0x1b, 0xaa, 0xa6, 0x20, 0x27, 0xb1, 0x52, 0x48, 0x82, 0x8b, 0x3d, 0x37, 0xb5, 0xb8, 0x38, 0x31,
159 | 0x1d, 0xa6, 0x0a, 0xc6, 0x55, 0x52, 0x80, 0x1a, 0xe6, 0x0b, 0xe1, 0x0b, 0x09, 0x70, 0x31, 0xe7,
160 | 0x16, 0xa7, 0x43, 0x55, 0x81, 0x98, 0x46, 0xdd, 0x8c, 0x50, 0xb3, 0x82, 0x53, 0x8b, 0xca, 0x52,
161 | 0x8b, 0x84, 0xac, 0xb9, 0x38, 0x82, 0x13, 0x2b, 0xc1, 0x22, 0x42, 0x62, 0x7a, 0x30, 0x57, 0xe9,
162 | 0x21, 0x3b, 0x49, 0x4a, 0x14, 0x43, 0x1c, 0xe4, 0x0c, 0x25, 0x06, 0x21, 0x7b, 0x2e, 0x6e, 0xf7,
163 | 0xd4, 0x12, 0x88, 0x8d, 0xc5, 0xe9, 0x38, 0xf5, 0xa3, 0x8b, 0x43, 0x5d, 0xa7, 0xc4, 0x90, 0xc4,
164 | 0x06, 0x96, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa4, 0xc8, 0x93, 0xa6, 0x1c, 0x01, 0x00,
165 | 0x00,
166 | }
167 |
168 | // Reference imports to suppress errors if they are not otherwise used.
169 | var _ context.Context
170 | var _ grpc.ClientConn
171 |
172 | // This is a compile-time assertion to ensure that this generated file
173 | // is compatible with the grpc package it is being compiled against.
174 | const _ = grpc.SupportPackageIsVersion4
175 |
176 | // HelloServerClient is the client API for HelloServer service.
177 | //
178 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
179 | type HelloServerClient interface {
180 | // 创建第一个接口
181 | SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReplay, error)
182 | // 创建第二个接口
183 | GetHelloMsg(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloMessage, error)
184 | }
185 |
186 | type helloServerClient struct {
187 | cc *grpc.ClientConn
188 | }
189 |
190 | func NewHelloServerClient(cc *grpc.ClientConn) HelloServerClient {
191 | return &helloServerClient{cc}
192 | }
193 |
194 | func (c *helloServerClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReplay, error) {
195 | out := new(HelloReplay)
196 | err := c.cc.Invoke(ctx, "/protocol.HelloServer/SayHello", in, out, opts...)
197 | if err != nil {
198 | return nil, err
199 | }
200 | return out, nil
201 | }
202 |
203 | func (c *helloServerClient) GetHelloMsg(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloMessage, error) {
204 | out := new(HelloMessage)
205 | err := c.cc.Invoke(ctx, "/protocol.HelloServer/GetHelloMsg", in, out, opts...)
206 | if err != nil {
207 | return nil, err
208 | }
209 | return out, nil
210 | }
211 |
212 | // HelloServerServer is the server API for HelloServer service.
213 | type HelloServerServer interface {
214 | // 创建第一个接口
215 | SayHello(context.Context, *HelloRequest) (*HelloReplay, error)
216 | // 创建第二个接口
217 | GetHelloMsg(context.Context, *HelloRequest) (*HelloMessage, error)
218 | }
219 |
220 | // UnimplementedHelloServerServer can be embedded to have forward compatible implementations.
221 | type UnimplementedHelloServerServer struct {
222 | }
223 |
224 | func (*UnimplementedHelloServerServer) SayHello(ctx context.Context, req *HelloRequest) (*HelloReplay, error) {
225 | return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
226 | }
227 | func (*UnimplementedHelloServerServer) GetHelloMsg(ctx context.Context, req *HelloRequest) (*HelloMessage, error) {
228 | return nil, status.Errorf(codes.Unimplemented, "method GetHelloMsg not implemented")
229 | }
230 |
231 | func RegisterHelloServerServer(s *grpc.Server, srv HelloServerServer) {
232 | s.RegisterService(&_HelloServer_serviceDesc, srv)
233 | }
234 |
235 | func _HelloServer_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
236 | in := new(HelloRequest)
237 | if err := dec(in); err != nil {
238 | return nil, err
239 | }
240 | if interceptor == nil {
241 | return srv.(HelloServerServer).SayHello(ctx, in)
242 | }
243 | info := &grpc.UnaryServerInfo{
244 | Server: srv,
245 | FullMethod: "/protocol.HelloServer/SayHello",
246 | }
247 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
248 | return srv.(HelloServerServer).SayHello(ctx, req.(*HelloRequest))
249 | }
250 | return interceptor(ctx, in, info, handler)
251 | }
252 |
253 | func _HelloServer_GetHelloMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
254 | in := new(HelloRequest)
255 | if err := dec(in); err != nil {
256 | return nil, err
257 | }
258 | if interceptor == nil {
259 | return srv.(HelloServerServer).GetHelloMsg(ctx, in)
260 | }
261 | info := &grpc.UnaryServerInfo{
262 | Server: srv,
263 | FullMethod: "/protocol.HelloServer/GetHelloMsg",
264 | }
265 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
266 | return srv.(HelloServerServer).GetHelloMsg(ctx, req.(*HelloRequest))
267 | }
268 | return interceptor(ctx, in, info, handler)
269 | }
270 |
271 | var _HelloServer_serviceDesc = grpc.ServiceDesc{
272 | ServiceName: "protocol.HelloServer",
273 | HandlerType: (*HelloServerServer)(nil),
274 | Methods: []grpc.MethodDesc{
275 | {
276 | MethodName: "SayHello",
277 | Handler: _HelloServer_SayHello_Handler,
278 | },
279 | {
280 | MethodName: "GetHelloMsg",
281 | Handler: _HelloServer_GetHelloMsg_Handler,
282 | },
283 | },
284 | Streams: []grpc.StreamDesc{},
285 | Metadata: "hello.proto",
286 | }
287 |
--------------------------------------------------------------------------------
/ch13/13.3/grpc/protocol/hello.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package protocol;
3 | service HelloServer{
4 | // 创建第一个接口
5 | rpc SayHello(HelloRequest)returns(HelloReplay){}
6 | // 创建第二个接口
7 | rpc GetHelloMsg(HelloRequest)returns(HelloMessage){}
8 | }
9 | message HelloRequest{
10 | string name = 1 ;
11 | }
12 | message HelloReplay{
13 | string message = 1;
14 | }
15 | message HelloMessage{
16 | string msg = 1;
17 | }
--------------------------------------------------------------------------------
/ch13/13.3/grpc/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 | import (
3 | "context"
4 | "fmt"
5 | "google.golang.org/grpc"
6 | pt "../protocol"
7 | "net"
8 | )
9 | const (
10 | post = "127.0.0.1:18887"
11 | )
12 | //对象要和proto内定义的服务一样
13 | type server struct{}
14 | //实现RPC SayHello 接口
15 | func(s *server)SayHello(ctx context.Context,in *pt.HelloRequest)(*pt.HelloReplay , error){
16 | return &pt.HelloReplay{Message:"hello"+in.GetName()},nil
17 | }
18 | //实现RPC GetHelloMsg 接口
19 | func (s *server) GetHelloMsg(ctx context.Context, in *pt.HelloRequest) (*pt.HelloMessage, error) {
20 | return &pt.HelloMessage{Msg: "this is from server!"}, nil
21 | }
22 | func main() { //监听网络
23 | ln ,err :=net.Listen("tcp",post)
24 | if err!=nil {
25 | fmt.Println("网络异常",err) }
26 | // 创建一个grpc的句柄
27 | srv:= grpc.NewServer()
28 | //将server结构体注册到 grpc服务中
29 | pt.RegisterHelloServerServer(srv,&server{})
30 | //监听grpc服务
31 | err= srv.Serve(ln)
32 | if err!=nil {
33 | fmt.Println("网络启动异常",err)
34 | }
35 | }
--------------------------------------------------------------------------------
/ch13/13.3/rpc/client/client.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bufio"
5 | "log"
6 | "net/rpc"
7 | "os"
8 | )
9 |
10 | func main() {
11 | client, err := rpc.Dial("tcp", "localhost:13133")
12 | if err != nil {
13 | log.Fatal(err)
14 | }
15 |
16 | in := bufio.NewReader(os.Stdin)
17 | for {
18 | line, _, err := in.ReadLine()
19 | if err != nil {
20 | log.Fatal(err)
21 | }
22 | var reply bool
23 | err = client.Call("Listener.GetLine", line, &reply)
24 | if err != nil {
25 | log.Fatal(err)
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/ch13/13.3/rpc/server/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net"
7 | "net/rpc"
8 | )
9 |
10 | type Listener int
11 |
12 | func (l *Listener) GetLine(line []byte, ack *bool) error {
13 | fmt.Println(string(line))
14 | return nil
15 | }
16 |
17 | func main() {
18 | addy, err := net.ResolveTCPAddr("tcp", "0.0.0.0:13133")
19 | if err != nil {
20 | log.Fatal(err)
21 | }
22 |
23 | inbound, err := net.ListenTCP("tcp", addy)
24 | if err != nil {
25 | log.Fatal(err)
26 | }
27 |
28 | listener := new(Listener)
29 | rpc.Register(listener)
30 | rpc.Accept(inbound)
31 | }
--------------------------------------------------------------------------------
/chapter0/sample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 | fmt.Println("Go代码示例!")
9 | }
10 |
--------------------------------------------------------------------------------
/chapter01/1.1/helloserver/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | func handler(w http.ResponseWriter,r *http.Request) {
10 | s := "你好,世界!"
11 | fmt.Fprintf(w,"%s",s)
12 | log.Printf("%s",s)
13 | }
14 | func main() {
15 | fmt.Println("server start.")
16 | http.HandleFunc("/",handler)
17 | if err := http.ListenAndServe("localhost:1234",nil); err != nil {
18 | log.Fatal("ListenAndServe:",err)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/chapter01/1.1/helloworld/hello:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ScottAI/book/5851b283d7dbfb91b42f5f4f1da4fbe6aec3acb4/chapter01/1.1/helloworld/hello
--------------------------------------------------------------------------------
/chapter01/1.1/helloworld/hello.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | fmt.Println("Hello,World!")
7 | }
8 |
--------------------------------------------------------------------------------
/chapter01/1.2/iota/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type data int
6 |
7 |
8 | const (
9 | Zero data = iota
10 | One
11 | Two
12 | Three
13 | Four
14 | )
15 |
16 | func main() {
17 |
18 | fmt.Println(Zero)
19 | fmt.Println(One)
20 | fmt.Println(Two)
21 | fmt.Println(Three)
22 | fmt.Println(Four)
23 | }
--------------------------------------------------------------------------------
/chapter01/1.2/pointer/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | m := 1
7 | selfPlusPointer(&m)
8 | fmt.Println(m)
9 | fmt.Println(*selfPlus(1))
10 | }
11 |
12 | func selfPlusPointer(n *int){
13 | *n++
14 | }
15 |
16 | func selfPlus(n int) *int {
17 | t := n+1
18 | return &t
19 | }
--------------------------------------------------------------------------------
/chapter01/1.2/var/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math/rand"
6 | )
7 |
8 |
9 | func main() {
10 | //多个变量一起通过类型声明
11 | var i,j,k int
12 | fmt.Printf("i:%d,j:%d,k:%d",i,j,k)
13 | fmt.Println()
14 | //多个变量一起通过表达式声明
15 | var a,b,c = 1,"s",true
16 | fmt.Printf("a:%d,b:%s,c:%t",a,b,c)
17 | fmt.Println()
18 | //声明赋值的缩写
19 | f := rand.Float64()*100
20 | fmt.Printf("f:%g",f)
21 | }
22 |
--------------------------------------------------------------------------------
/chapter01/1.4/loop.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | for i:=0;i<10;i++{
7 | if i%2 == 0{
8 | continue
9 | }
10 | fmt.Print(i," ")
11 | }
12 | fmt.Println()
13 | i := 5
14 | for{
15 | if i<1 {
16 | break
17 | }
18 | fmt.Print(i," ")
19 | i--
20 | }
21 |
22 | fmt.Println()
23 | arr := []int{1,2,3,4,5}
24 | for i,v := range arr{
25 | fmt.Println("index:",i,"value:",v)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------