Go语言实战 (William,Kennedy 等著)

第1章 关于Go语言的介绍 (已看)

  1.1 用Go解决现代编程难题

    1.1.1 开发速度

    1.1.2 并发

      1. goroutine

      2. 通道

    1.1.3 Go语言的类型系统

      1. 类型简单

      2. Go接口对一组行为建模

    1.1.4 内存管理

  1.2 你好,Go

    介绍Go playground

第2章 快速开始一个Go程序

  2.1 程序架构

  2.2 main包

  2.3 search包

    2.3.1 search.go

    2.3.2 feed.go

    2.3.3 match.go/default.go

  2.4 RSS匹配器

  2.5 小结

第3章 打包和工具链 (已看)

  3.1 包

    3.1.1 包名惯例

    3.1.2 main包

  3.2 导入

    3.2.1 远程导入

    3.2.2 命名导入

  3.3 函数init

  3.4 使用Go的工具

package main

import (
    "fmt"
    "chapter3/words"
    "io/ioutil"
    "os"
)

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

    contents,err := ioutil.ReadFile(filename)

    if err != nil {
        fmt.Println(err)
        return
    }

    text := string(contents)

    count := words.CountWords(text)
    fmt.Printf("There are %d word in your text. \n",count)
}
View Code

  3.5 进一步介绍Go开发工具

    3.5.1 go vet

    3.5.2 Go代码格式化

    3.5.3 Go语言的文档

      1. 从命令行获取文档

      2. 浏览文档

  3.6 与其他Go开发者合作

    以分享为目的创建代码库

      1. 包应该在代码库的根目录中

      2. 包可以非常小

      3. 对代码执行go fmt

      4. 给代码写文档

  3.7 依赖管理

    3.7.1 第三方依赖

    3.7.2 对gb的介绍

  3.8 小结

第4章 数组,切片和映射 (已看)

  4.1 数组的内部实现和基础功能

var array [5]int

array := [5]int{10,20,30,40,50}

array := [...]int{10,20,30,40,50}

array := [5]int{1:10,2:20}

array := [5]{10,20,30,40,50}
array[2] = 35

array := [5]*int{0:new(int),1:new(int)}
*array[0] = 10
*array[1] = 20

var array1 [5]string
array2 := [5]string{"Red","Blue","Green","Yellow","Pink"}
array1 = array2

var array1 [4]string
array2 := [5]string{"Red","Blue","Green","Yellow","Pink"}
array1 = array2
Compiler Error:
cannot use array2 (type [5]string) as type [4]string in assignment

var array1 [3]*string
array2 := [3]*string{new(string),new(string),new(string)}
*array2[0] = "Red"
*array2[1] = "Blue"
*array2[2] = "Green"
array1 = array2

var array [4][2]int
array := [4][2]int{{10,11},{20,21},{30,31},{40,41}}
array := [4][2]int{1:{20,21},3:{40,41}}
array := [4][2]int{1:{0:20},3{1:41}}

var array [2][2]int
array[0][0] = 10
array[0][1] = 20
array[1][0] = 30
array[1][1] = 40

var array1 [2][2]int
var array2 [2][2]int
array2[0][0] = 10
array2[0][1] = 20
array2[1][0] = 30
array2[1][1] = 40
array1 = array2
var array3 [2]int = array1[1]
var value int = array1[1][0]

var array [1e6]int
foo(array)
func foo(array [1e6]int) {
    ...
}

var array [1e6]int
foo(&array)
func foo(array *[1e6]int) {
    ...
}
View Code

    4.1.1 内部实现

    4.1.2 声明和初始化

    4.1.3 使用数组

    4.1.4 多维数组

    4.1.5 在函数间传递数组

  4.2 切片的内部实现和基础功能

slice := make([]string,5)

slice := make([]string,3,5)

slice := make([]string,5,3)
Compiler Error:
len larger than cap in make([]int)

slice := []string{"Red","Blue","Green","Yellow","Pink"}
slice := []int{10,20,30}

slice := []string{99:""}

array := [3]int{10,20,30}
slice := []int{10,20,30}

var slice []int    // 创建nil整型切片

slice := make([]int,0)
slice := []int{}

slice := []int{10,20,30,40,50}
slice[1] = 25

slice := []int{10,20,30,40,50}
newSlice := slice[1:3]
newSLice[1] = 35

slice := []int{10,20,30,40,50}
newSlice := slice[1:3]
newSlice[3] = 45
Runtime Exception:
panic: runtime error: index out of range

slice := []int{10,20,30,40,50}
newSlice := slice[1:3]
newSlice = append(newSlice,60)

slice := []int{10,20,30,40}
newSlice := append(slice,50)

souce := []string{"Apple","Orange","Plum","Banana","Grape"}
slice := source[2:3:4]
slice := source[2:3:6]

Runtime Error:
panic: runtime error: slice bounds out of range

s1 := []int{1,2}
s2 := []int{3,4}
fmt.Printf("%v\n",append(s1,s2...))

Output:
[1 2 3 4]

slice := []int{10,20,30,40}
for index,value := range slice {
    fmt.Printf("Index: %d value: %d\n",index,value)
}

Output:
Index: 0 Value: 10
Index: 1 Value: 20
Index: 2 Value: 30
Index: 3 Value: 40

slice := []int{10,20,30,40}
for index,value := range slice {
    fmt.Printf("Value: %d Value-Addr: %X ElementAddr: %X\n", value,&value,&slice[index])
}

Output:
Value: 10 Value-Addr: 10500168 ElemAddr: 1052E100
Value: 20 Value-Addr: 10500168 ElemAddr: 1052E104

slice := []int{10,20,30,40}
for index := 2;index < len(slice);index++ {
    fmt.Printf("Index: %d Value:%d\n",index,slice[index])
}

slice := [][]int{{10},{100,200}}

slice := [][]int{{10},{100,200}}
slice[0] = append(slice[0],20)

slice := make([]int,1e6)
slice = foo(slice)
func foo(slice []int) []int {
    ...
    return slice
}
View Code

    4.2.1 内部实现

    4.2.2 创建和初始化

      1. make和切片字面量

      2. nil和空切片

    4.2.3 使用切片

      1. 赋值和切片

      2. 切片增长

      3. 创建切片时的3个索引

      4. 迭代切片

    4.2.4 多维切片

    4.25 在函数间传递切片

  4.3 映射的内部实现和基础功能

dict := make(map[string]int)
dict := map[string]string{"Red":"#da1137","Orange":"#e95a22"}

dict := map[[]string]int{}
Compiler Exception:
invalid map key type []string

dict := map[int][]sting{}

colors := map[string]string{}
colors["Red"] = "#da1337"

var colors map[string]string

colors["Red"] = "#da1337"

Runtime Error:
panic: runtime error: assignment to entry in nil map

value,exsits := colors["Blue"]
if exists {
    fmt.Println(value)
}

value := colors["Blue"]
if value != "" {
    fmt.Println(value)
}

colors := map[string]string{
    "AliceBlue": "#f0f8ff",
    "Coral":     "#ff7F50",
    "DarkGray":     "#a9a9a9",
    "ForestGreen":"#228b22",
}

for key,value := range colors {
    fmt.Printf("Key: %s Value: %s\n",key,value)
}

delete(colors,"Coral")
for key,value := range colors {
    fmt.Printf("Key: %s Value: %s\n",key,value)
}

func main() {
    colors: = map[string]string {
        "AliceBlue": "#f0f8ff",
        "Coral": "#ff7F50",
        "DarkGray": "#a9a9a9",
        "ForestGreen": "#228b22",
    }
    
    for key,value := range colors {
        fmt.Printf("Key: %s Value: %s\n",key,value)
    }
    
    removeColor(colors,"Coral")
    
    for key,value := range colors {
        fmt.Printf("Key: %s Value: %s\n",key,value)
    }
}

func removeColor(colors map[string]string,key string) {
    delete(colors,key)
}
View Code

    4.3.1 内部实现

    4.3.2 创建和初始化

    4.3.3 使用映射

    4.3.4 在函数间传递映射

  4.4 小结

第5章 Go语言的类型系统 (已看)

  5.1 用户定义的类型

type user struct {
    name string
    email string
    ext int
    privileged bool
}

var bill user

lisa := user{
    name: "Lisa",
    email: "lisa@email.com",
    ext:123,
    privileged:true,
}

user{
    name: "Lisa",
    email:"lisa@email.com",
    ext:123,
    priviledged:true,
}

lisa := user{"Lisa","lisa@email.com",123,true}

type admin struct {
    person user
    level string
}

fred := admin{
    person:user {
        name: "Lisa",
        email: "lisa@email.com",
        ext: 123,
        priviledged:true,
    },
    level:"super",
}

type Duration int64

package main

type Duration int64

func main() {
    var dur Duration
    dur = int64(1000)
}

cannot use int64(1000) (type in64) as type Duration in assignment
View Code

  5.2 方法

package main

import (
    "fmt"
)

type user struct {
    name string
    email string
}

func (u user) notify() {
    fmt.Printf("Sending User Email To %s<%s>\n",u.name,u.email)
}

func (u *user) changeEmail(email string) {
    u.email = email
}

func main() {
    // user类型的值可以用来调用使用值接收者声明的方法
    bill := user{"Bill","bill@email.com"}
    bill.notify()
    // 指向user类型值的指针也可以用来调用使用值接收者声明的方法
    lisa := &user{"Lisa","lisa@email.com"}
    lisa.notify()
    (*lisa).notify()
    // user类型的值可以用来调用使用指针接收者声明的方法
    bill.changeEmail("bill@newdomain.com")
    (&bill).changeEmail("bill@newdomain.com")
    bill.notify()
    // 指向user类型值的指针可以用来调用使用指针接收者声明的方法
    lisa.changeEmail("lisa@newdomain.com")
    lisa.notify()
}
View Code

  5.3 类型的本质

type Time struct {
    sec int64
    nsec int32
    loc *Location
}

func Now() Time {
    sec,nsec := now()
    return Time{sec + unixToInternal,nsec,Local}
}

func (t Time) Add(d Duration) Time {
    t.sec += int64(d/1e9)
    nsec := int32(t.nsec) + int32(d%1e9)
    if nesc >= 1e9 {
        t.sec++
        nsec -= 1e9
    } else if nsec < 0 {
        t.sec--
        nsec += 1e9
    }
    t.nsec = nsec
    return t
}

type File struct {
    *file
}

type file struct {
    fd int
    name string
    dirinfo *dirInfo
    nepipe int32
}

func Open(name string) (file *File,err error) {
    return OpenFile(name,O_RDONLY,0)
}

func (f *File) Chdir() error {
    if f == nil {
        return ErrInvalid
    }
    if e := syscall.Fchdir(f.fd); e != nil {
        return &PathError{"chdir",f.name,e}
    }
    return nil
}
View Code

    5.3.1 内置类型

    5.3.2 引用类型

    5.3.3 结构类型

  5.4 接口

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func init() {
    if len(os.Args) != 2 {
        fmt.Println("Usage: ./example2 <url>")
        os.Exit(-1)
    }
}

func main() {
    r,err := http.Get(os.Args[1])
    if err != nil {
        fmt.Println(err)
        return
    }
    
    io.Copy(os.Stdout,r.Body)
    if err := r.Body.Close(); err != nil {
        fmt.Println(err)
    }
}

package main

import (
    "bytes"
    "fmt"
    "io"
    "os"
)

func main() {
    var b bytes.Buffer
    b.Write([]byte("Hello"))
    fmt.Fprintf(&b,"World!")
    io.Copy(os.Stdout,&b)
}


package main

import (
    "fmt"
)

type notifier interface {
    notify()
}

type user struct {
    name string
    email string
}

func (u *user) notify() {
    fmt.Printf("Sending user email to %s<%s>\n",u.name,u.email)
}

func main() {
    u := user{"Bill","bill@email.com"}
    
    sendNotification(&u)    
}

func sendNotification(n notifier) {
    n.notify()
}

package main

import (
    "fmt"
)

type notifier interface {
    notify()
}

type user struct {
    name string
    email string
}

func (u *user) notify() {
    fmt.Printf("Sending user email to %s<%s>\n",u.name,u.email)
}

type admin struct {
    name string
    email string
}

func (a *admin) notify() {
    fmt.Printf("Sending admin email to %s<%s>\n",a.name,a.email)
}

func main () {
    bil := user{"Bill","bill@email.com"}
    sendNotification(&bill)
    
    lisa := admin{"Lisa","lisa@email.com"}
    sendNotification(&lisa)
}

func sendNotification(n notifier) {
    n.notify()
}
View Code

    5.4.1 标准库

    5.4.2 实现

    5.4.3 方法集

    5.4.4 多态

  5.5 嵌入类型

package main

import (
    "fmt"
)

type user struct {
    name string
    email string
}

func (u *user) notify() {
    fmt.Printf("Sending user email to %s<%s>\n",u.name,u.email)
}

type admin struct {
    user
    level string
}

func main() {
    ad := admin {
        user: user{
            name: "john smith",
            email: "john@yahoo.com",
        },
        level: "super"
    }
    
    ad.user.notify()
    
    ad.notify()
}

package main

import (
    "fmt"
)

type notifier interface {
    notify()
}

type user struct {
    name string
    email string
}

func (u *user) notify() {
    fmt.Printf("Sending user email to %s<%s>\n",u.name,u.email)
}

type admin struct {
    user
    level string
}

func main() {
    ad := admin{
        user: user{
            name: "john smith",
            email: "john@yahoo.com",
        },
        level: "super",
    }
    
    sendNotification(&ad)
}

func sendNotification(n notifier) {
    n.notify()
}
View Code

  5.6 公开或未公开的标识符

  5.7 小结

第6章 并发

  6.1 并发与并行

  6.2 goroutine

package main

import (
    "runtime"
    "sync"
    "fmt"
)

func main() {
    runtime.GOMAXPROCS(1)

    var wg sync.WaitGroup
    wg.Add(2)

    fmt.Println("Start Gorountines")

    go func() {
        defer wg.Done()

        for count := 0; count < 3; count++ {
            for char := 'a'; char < 'a' + 26; char++ {
                fmt.Printf("%c ",char)
            }
        }
    }()

    go func() {
        defer wg.Done()

        for count := 0; count < 3; count++ {
            for char := 'A'; char < 'A' + 26; char++ {
                fmt.Printf("%c ",char)
            }
        }
    }()

    fmt.Println("Waiting To Finish")
    wg.Wait()

    fmt.Println("\nTerminating Program")
}

package main

import (
    "sync"
    "runtime"
    "fmt"
)

var wg sync.WaitGroup

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    wg.Add(2)

    fmt.Println("Create Goroutines")
    go printPrime("A")
    go printPrime("B")

    fmt.Println("Waiting To Finish")
    wg.Wait()

    fmt.Println("Terminating Program")
}

func printPrime(prefix string) {
    defer wg.Done()

    next:
        for outer := 2; outer < 5000; outer++ {
            for inner := 2; inner < outer; inner++ {
                if outer % inner == 0 {
                    continue next
                }
            }
            fmt.Printf("%s:%d\n",prefix,outer)
        }
        fmt.Println("Completed",prefix)
}
View Code

  6.3 竞争状态

// 这个示例程序展示如何在程序里造成竞争状态
// 实际上不希望出现这种情况

package main

import (
    "sync"
    "runtime"
    "fmt"
)

var (
    counter int
    wg sync.WaitGroup
)

func main() {
    wg.Add(2)

    go incCounter(1)
    go incCounter(2)

    wg.Wait()

    fmt.Println("Final Counter:",counter)
}

func incCounter(id int) {
    defer wg.Done()

    for count := 0; count < 2; count++ {
        value := counter

        runtime.Gosched()

        value++

        counter = value
    }
}
View Code

  6.4 锁住共享资源

    6.4.1 原子函数

package main

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

var (
    shutdown int64
    wg sync.WaitGroup
)

func main() {
    wg.Add(2)

    go doWork("A")
    go doWork("B")

    time.Sleep(1 * time.Second)

    fmt.Println("Shutdown Now")
    atomic.StoreInt64(&shutdown,1)

    wg.Wait()
}

func doWork(name string) {
    defer wg.Done()

    for {
        fmt.Printf("Doing %s Work\n",name)
        time.Sleep(250 * time.Millisecond)

        if atomic.LoadInt64(&shutdown) == 1 {
            fmt.Printf("Shutting %s Down\n",name)
            break
        }
    }
}
View Code

    6.4.2 互斥锁

package main

import (
    "sync"
    "runtime"
    "fmt"
)

var (
    counter int
    wg sync.WaitGroup
    mutex sync.Mutex
)

func main() {
    wg.Add(2)

    go incCounter(1)
    go incCounter(2)

    wg.Wait()
    fmt.Printf("Final Counter: %d\n",counter)
}

func incCounter(id int) {
    defer wg.Done()

    for count := 0; count < 2; count++ {
        mutex.Lock()
        {
            value := counter
            runtime.Gosched()
            value++
            counter = value
        }
        mutex.Unlock()
    }
}
View Code

  6.5 通道

    6.5.1 无缓冲的通道

package main

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

var wg sync.WaitGroup

func init() {
    rand.Seed(time.Now().UnixNano())
}

func main() {
    court := make(chan int)

    wg.Add(2)

    go player("Nadal",court)
    go player("Djokovic",court)

    court <- 1

    wg.Wait()
}

func player(name string,court chan int) {
    defer wg.Done()

    for {
        ball,ok := <-court

        if !ok {
            fmt.Printf("Player %s Won\n",name)
        }

        n := rand.Intn(100)
        if n % 13 == 0 {
            fmt.Printf("number=%s Player %s Missed\n",n,name)
            close(court)
            return
        }

        fmt.Printf("Player %s Hit %d\n",name,ball)
        ball++

        court <- ball
    }
}

package main

import (
    "sync"
    "fmt"
    "time"
)

var wg sync.WaitGroup

func main() {
    baton := make(chan int)
    wg.Add(1)

    go Runner(baton)

    baton<-1
    wg.Wait()
}

func Runner(baton chan int) {
    var newRunner int

    runner := <-baton
    fmt.Printf("Runner %d Running With Baton\n",runner)
    if runner != 4 {
        newRunner = runner + 1
        fmt.Printf("Runner %d To The Line\n",newRunner)
        go Runner(baton)
    }

    time.Sleep(100 * time.Millisecond)

    if runner == 4 {
        fmt.Printf("Runner %d Finished,Race Over\n",runner)
        wg.Done()
        return
    }

    fmt.Printf("Runner %d Exchange With Runner %d\n",runner,newRunner)

    baton <-newRunner
}
View Code

    6.5.2 有缓冲的通道

package main

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

const (
    numberGoroutines = 4
    taskLoad = 10
)

var wg sync.WaitGroup

func int() {
    rand.Seed(time.Now().Unix())
}

func main() {
    tasks := make(chan string,taskLoad)

    wg.Add(numberGoroutines)
    for gr := 1; gr <= numberGoroutines; gr++ {
        go worker(tasks,int64(gr))
    }

    for post := 1; post <= taskLoad; post++ {
        tasks <- fmt.Sprintf("Task: %d",post)
    }

    close(tasks)

    wg.Wait()
}



func worker(tasks chan string,worker int64){
    defer wg.Done()

    for {
        task,ok := <-tasks
        if !ok {
            fmt.Printf("Worker: %d : Shutting Down\n",worker)
            return
        }

        fmt.Printf("Worker: %d : Started %s\n",worker,task)

        sleep := rand.Int63n(100)
        time.Sleep(time.Duration(sleep) * time.Millisecond)

        fmt.Print("Worker: %d : Completed %s\n",worker,task)
    }
}
View Code

第7章 并发模式

  7.1 runner

  7.2 pool

  7.3 work

  7.4 小结

第8章 标准库

  8.1 文档与源代码

  8.2 记录日志

    8.2.1 log包

    8.2.2 定制的日志记录器

    8.2.3 结论

  8.3 编码/解码

    8.3.1 解码JSON

    8.3.2 编码JSON

    8.3.3 结论

  8.4 输入和输出

    8.4.1 Writer和Reader接口

    8.4.2 整合并完成工作

    8.4.3 简单的curl

    8.4.4 结论

  8.5 小结

第9章 测试和性能

  9.1 单元测试

    9.1.1 基础单元测试

    9.1.2 表组测试

    9.1.3 模仿调用

    9.1.4 测试服务端点

  9.2 示例

  9.3 基准测试

  9.4 小结

转载于:https://www.cnblogs.com/revoid/p/9242991.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值