Go程序语言设计

第1章 入门  (已看)

  1.1 hello,world

package main

import "fmt"

func main(){
    fmt.Println("Hello,World")  
}
Hello,World

$go run HelloWorld.go

$go build HelloWorld.go

  1.2 命令行参数

package main

import (
    "fmt"
    "os"
)

func main(){
    var s,sep string
    for i :=1; i < len(os.Args);i++ {
        s += sep + os.Args[i]
        sep = " "
    }
    fmt.Println(s)
}
echo1
package main

import (
    "fmt"
    "os"
)

func main(){
    s,sep:="",""
    for _,arg:=range os.Args[1:] {
        s += sep + arg
        sep = " "
    }
    fmt.Println(s)
}
echo2

  1.3 找出重复行

  1.4 GIF动画

  1.5 获取一个URL

  1.6 并发获取多个URL

  1.7 一个Web服务器

  1.8 其他内容

第2章 程序结构 (已看)

  2.1 名称

  2.2 声明

  2.3 变量

    2.3.1 短变量声明

    2.3.2 指针

    2.3.3 new函数

    2.3.4 变量的生命周期

  2.4 赋值

    2.4.1 多重赋值

    2.4.2 可赋值性

  2.5 类型声明

  2.6 包和文件

    2.6.1 导入

    2.6.2 包初始化

  2.7 作用域

第3章 基本数据 (已看)

  3.1 整数

  3.2 浮点数

package main

import (
    "fmt"
    "math"
)

const (
    width,height = 600,320
    cells = 100
    xyrange = 30.0
    xyscale = width/2/xyrange
    zscale = height * 0.4
    angle = math.Pi / 6
)

var sin30,cos30 = math.Sin(angle),math.Cos(angle)

func main(){
    fmt.Printf("<svg xmlns = 'http://www.w3.org/2000svg' " +
        "style='stroke:grey;fill:white;stroke-width:0.7' " +
        "width='%d' height='%d'>",width,height)
        
    for i := 0; i < cells; i++ {
        for j := 0;j < cells;j++ {
            ax,ay := corner(i+1,j)
            bx,by := corner(i,j)
            cx,cy := corner(i,j+1)
            dx,dy := corner(i+1,j+1)
            fmt.Printf("<polygon points='%g,%g %g,%g %g,%g %g,%g'/>\n",
                ax,ay,bx,by,cx,cy,dx,dy)
        }
    }
    fmt.Println("</svg>")
}

func corner(i,j int)(float64,float64) {
    x := xyrange * (float64(i)/cells-0.5)
    y := xyrange * (float64(j)/cells-0.5)
    
    z := f(x,y)
    sx := width/2 + (x-y)*cos30*xyscale
    sy := height/2 + (x+y)*sin30*xyscale - z*zscale
    return sx,sy
}

func f(x,y float64) float64 {
    r := math.Hypot(x,y)
    return math.Sin(r)
}
surface

  3.3 复数

package main

import (
    "image"
    "image/color"
    "image/png"
    "math/cmplx"
    "os"
)

func main(){
    const (
        xmin,ymin,xmax,ymax = -2,-2,+2,+2
        width,height = 1024,1024
    )
    
    img := image.NewRGBA(image.Rect(0,0,width,height))
    for py := 0;py < height;py++ {
        y := float64(py)/height*(ymax-ymin)
        for px := 0;px < width;px++ {
            x := float64(px)/width*(xmax-xmin) + xmin
            z := complex(x,y)
            
            img.Set(px,py,mandelbrot(z))
        }
    }
    png.Encode(os.Stdout,img)
}

func mandelbrot(z complex128) color.Color {
    const iterations = 200
    const contrast = 15
    
    var v complex128
    for n := uint8(0);n < iterations;n++ {
        v = v*v + z
        if cmplx.Abs(v) > 2 {
            return color.Gray{255 - contrast*n}
        }
    }
    return color.Black
}
mandelbrot

  3.4 布尔值

  3.5 字符串

    3.5.1 字符串字面量

    3.5.2 Unicode

    3.5.3 UTF-8

    3.5.4 字符串和字节slice

package main

import (
    "fmt"
    "bytes"
)

func intsToString(values []int) string {
    var buf bytes.Buffer
    buf.WriteByte('[')
    for i,v := range values {
        if i > 0 {
            buf.WriteString(", ")
        }
        fmt.Fprintf(&buf,"%d",v)
    }
    buf.WriteByte(']')
    return buf.String()
}

func main() {
    fmt.Println(intsToString([]int{1,2,3}))
}
printints

    3.5.5 字符串和数字的相互转换

  3.6 常量

    3.6.1 常量生成器iota

    3.6.2 无类型常量

第4章 复合数据类型 (已看)

  4.1 数组

package main

import (
    "fmt"
    "crypto/sha256"
)

type Currency int

const (
    USD Currency = iota
    EUR
    GBP
    RMB
)



func main(){

    var a [3]int
    fmt.Println(a[0])
    fmt.Println(a[len(a)-1])
    
    for i,v := range a {
        fmt.Printf("%d %d\n",i,v)
    }
    
    for _,v := range a {
        fmt.Printf("%d\n",v)
    }

    c1 := sha256.Sum256([]byte("x"))
    c2 := sha256.Sum256([]byte("X"))
    
    fmt.Printf("%x\n%x\n%t\n%T\n",c1,c2,c1 == c2,c1)
}
sha256

  4.2 slice

package main

import "fmt"

func reverse(s []int){
    for i,j :=0,len(s)-1;i < j;i,j = i+1,j-1 {
        s[i],s[j] = s[j],s[i]
    }
}

func main(){
    a := [...]int{0,1,2,3,4,5}
    reverse(a[:])
    fmt.Println(a)
}
rev

    4.2.1 append函数

package main

import "fmt"


func AppendInt(x []int,y int) []int {
    var z []int
    zlen := len(x) + 1
    if zlen <= cap(x) {
        z = x[:zlen]
    } else {
        zcap := zlen
        if zcap < 2*len(x) {
            zcap = 2 * len(x)
        }
        z = make([]int,zlen,zcap)
        copy(z,x)
    }
    z[len(x)] = y
    return z
}

func main(){
    var x,y []int
    for i := 0;i < 10;i++ {
        y = AppendInt(x,i)
        fmt.Printf("%d cap=%d\t%v\n",i,cap(y),y)
        x = y
    }
}
append

    4.2.2 slice就地修改

  4.3 map

package main

import (
    "bufio"
    "os"
    "fmt"
)


func main() {
    seen := make(map[string]bool)
    input := bufio.NewScanner(os.Stdin)
    
    for input.Scan() {
        line := input.Text()
        if !seen[line] {
            seen[line] = true
            fmt.Println(line)
        }
    }
    
    if err := input.Err();err != nil {
        fmt.Fprintf(os.Stderr,"dedup: %v\n",err)
        os.Exit(1)
    }
}
dedup
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "unicode"
    "unicode/utf8"
)

func main() {
    counts := make(map[rune]int)
    var utflen [utf8.UTFMax + 1]int
    invalid := 0
    
    in := bufio.NewReader(os.Stdin)
    for {
        r,n,err := in.ReadRune()
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Fprintf(os.Stderr,"charcount: %v\n",err)
            os.Exit(1)
        }
        if r == unicode.ReplacementChar && n == 1 {
            invalid++
            continue
        }
        counts[r]++
        utflen[n]++
    }
    fmt.Printf("rune\tcount\n")
    for c,n := range counts {
        fmt.Printf("%q\t%d\n",c,n)
    }
    fmt.Print("\nlen\tcount\n")
    for i,n := range utflen {
        if i > 0 {
            fmt.Printf("%d\t%d\n",i,n)
        }
    }
    if invalid > 0 {
        fmt.Printf("\n%d invalid UTF-8 characters\n",invalid)
    }
}
charcount
var graph = make(map[string]map[string]bool)

func addEdge(from,to string) {
    edges := graph[from]
    if edges == nil {
        edges = make(map[string]bool)
        graph[from] = edges
    }
    edges[to] = true
}

func hasEdge(from,to string) bool {
    return graph[from][to]
}
graph  

  4.4 结构体

    4.4.1 结构体字面量

    4.4.2 结构体比较

    4.4.3 结构体嵌套和匿名成员

package main

import "fmt"

type Point struct {
    X,Y int
}

type Circle struct {
    Point
    Radius int
}

type Wheel struct {
    Circle
    Spokes int
}

func main() {
    var w = Wheel{Circle{Point{8,8},5},20}


    fmt.Printf("%#v\n",w)
    w.X = 42
    fmt.Printf("%#v\n",w)
}
embed

  4.5 JSON

  4.6 文本和HTML模板

第5章 函数 (已看)

  5.1 函数声明

package main

import "fmt"

func add(x int,y int) int { return x+y }
func sub(x,y int) (z int) { z = x-y; return }
func first(x int,_ int) int { return x }
func zero(int,int) int { return 0 }

func main() {
    fmt.Printf("%T\n",add)
    fmt.Printf("%T\n",sub)
    fmt.Printf("%T\n",first)
    fmt.Printf("%T\n",zero)
}
funcTest

  5.2 递归

  5.3 多返回值

  5.4 错误

    5.4.1 错误处理策略

    5.4.2 文件结束标识

  5.5 函数变量

package main

import "fmt"

func square(n int) int { return n*n }
func negative(n int) int { return -n }
func product(m,n int) int { return m*n }


func main() {
    f := square
    fmt.Println(f(3))
    fmt.Printf("%T\n",f)
    
    f = negative
    fmt.Println(f(3))
    fmt.Printf("%T\n",f)
    
}
funcVarTest

  5.6 匿名函数

package main

import "fmt"

func squares() func() int {
    var x int
    return func() int {
        x++
        return x * x
    }
}

func main() {
    f := squares()
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
    fmt.Println(f())
}
squares

  5.7 变长函数

package main

import "fmt"

func sum(vals ...int) int {
    total := 0
    for _,val := range vals {
        total += val
    }
    return total
}

func main() {
    fmt.Println(sum())
    fmt.Println(sum(3))
    fmt.Println(sum(1,2,3,4))
}
sum

  5.8 延迟函数调用

  5.9 宕机

  5.10 恢复

第6章 方法 (已看)

  6.1 方法声明

package main

import "math"
import "fmt"

type Point struct{ X,Y float64 }

func Distance(p,q Point) float64 {
    return math.Hypot(q.X - p.X,q.Y - p.Y)
}

func (p Point) Distance(q Point) float64 {
    return math.Hypot(q.X - p.X,q.Y - p.Y)
}

func main() {
    p := Point{1,2}
    q := Point{4,6}

    fmt.Println(Distance(p,q))
    fmt.Println(p.Distance(q))
}
geometry

  6.2 指针接收者的方法

  6.3 通过结构体内嵌组成类型

  6.4 方法变量与表达式

p := Point{1,2}
q := Point{4,6}

distanceFromP := p.Distance
fmt.Println(distanceFromP(q))
var orgin Point
fmt.Println(distanceFromP(origin))

scaleP := p.ScaleBy
scaleP(2)
scaleP(3)
scaleP(10)
geometryTest1

  6.5 示例:位向量

  6.6 封装

第7章 接口

  7.1 接口即约定

  7.2 接口类型

package io

type Reader interface {
    Read(p []byte) (n int,err error)
}

type Closer interface {
    Close() error
}

type ReadWriter interface {
    Reader
    Writer
}

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}

type ReadWriter interface {
    Read(p []byte) (n int,err error)
    Write(p []byte) (n int,err error)
}

type ReadWriter interface {
    Read(p []byte) (n int,err error)
    Writer
}
interfaceType

  7.3 实现接口

  7.4 使用flag.Value来解析参数

  7.5 接口值

  7.6 使用sort.Interface来排序

  7.7 http.Handle接口

  7.8 error接口

  7.9 示例:表达式求值器

  7.10 类型断言

  7.11 使用类型断言来识别错误

  7.12 通过接口类型断言来查询特性

  7.13 类型分支

  7.14 示例:基于标记的XML解析

  7.15 一些建议

第8章 goroutine和通道

  8.1 goroutine

  8.2 示例:并发时钟服务器

  8.3 示例:并发回声服务器

  8.4 通道

    8.4.1 无缓冲通道

    8.4.2 管道

    8.4.3 单向通道类型

    8.4.4 缓冲通道

  8.5 并行循环

  8.6 示例:并发的Web爬虫

  8.7 使用select多路复用

  8.8 示例:并发目录遍历

  8.9 取消

  8.10 示例:聊天服务器

第9章 使用共享变量实现并发

  9.1 竞态

  9.2 互斥锁:sync.Mutex

  9.3 读写互斥锁:sync.RWMutex

  9.4 内存同步

  9.5 延迟初始化:sync.Once

  9.6 竞态检测器

  9.7 示例:并发非阻塞缓存

  9.8 goroutine与线程

    9.8.1 可增长的栈

    9.8.2 goroutine调度

    9.8.3 GOMAXPROCS

    9.8.4 goroutine没有标识

第10章 包和go工具 (已看)

  10.1 引言

  10.2 导入路径

  10.3 包的声明

  10.4 导入声明

  10.5 空导入

  10.6 包及其命名

  10.7 go工具

    10.7.1 工作空间的组织

    10.7.2 包的下载

    10.7.3 包的构建

    10.7.4 包的文档化

    10.7.5 内部包

    10.7.6 包的查询

第11章 测试

  11.1 go test工具

  11.2 Test函数

    11.2.1 随机测试

    11.2.2 测试命令

    11.2.3 白盒测试

    11.2.4 外部测试包

    11.2.5 编写有效测试

    11.2.6 避免脆弱的测试

  11.3 覆盖率

  11.4 Benchmark函数

  11.5 性能剖析

  11.6 Example函数

第12章 反射

  12.1 为什么使用反射

  12.2 reflect.Type和reflect.Value

package main

import (
    "fmt"
    "reflect"
    "os"
    "io"
)

func main() {
    t := reflect.TypeOf(3)
    fmt.Println(t.String())
    fmt.Println(t)
    fmt.Printf("%T\n",3)
    
    v := reflect.ValueOf(3)
    fmt.Println(v)
    fmt.Printf("%v\n",v)
    fmt.Println(v.String())
    
    t1 := v.Type()
    fmt.Println(t1.String())
    
    v1 := reflect.ValueOf(3)
    fmt.Println(v1)
    x := v.Interface()
    fmt.Println(x)
    i := x.(int)
    fmt.Printf("%d\n",i)
    
    var w io.Writer = os.Stdout
    fmt.Println(reflect.TypeOf(w))
    
}
reflectTest1
package main

import (
    "reflect"
    "strconv"
    "fmt"
    "time"
)

func Any(value interface{}) string {
    return formatAtom(reflect.ValueOf(value))
}

func formatAtom(v reflect.Value) string {
    switch v.Kind() {
    case reflect.Invalid:
        return "invalid"
    case reflect.Int,reflect.Int8,reflect.Int16,reflect.Int32,reflect.Int64:
        return strconv.FormatInt(v.Int(),10)
    case reflect.Uint,reflect.Uint8,reflect.Uint16,reflect.Uint32,reflect.Uint64,reflect.Uintptr:
        return strconv.FormatUint(v.Uint(),10)
    case reflect.Bool:
        return strconv.FormatBool(v.Bool())
    case reflect.String:
        return strconv.Quote(v.String())
    case reflect.Chan,reflect.Func,reflect.Ptr,reflect.Slice,reflect.Map:
        return v.Type().String() + "0x" + strconv.FormatUint(uint64(v.Pointer()),16)
    default:
        return v.Type().String() + " value"
    }
}

func main() {
    var x int64 = 1
    var d time.Duration = 1 * time.Nanosecond
    fmt.Println(Any(x))
    fmt.Println(Any(d))
    fmt.Println(Any([]int64{x}))
    fmt.Println(Any([]time.Duration{d}))
}
format

  12.3 Display:一个递归的值显示器

  12.4 示例:编码S表达式

  12.5 使用reflect.Value来设置值

  12.6 示例:解码S表达式

  12.7 访问结构体字段标签

  12.8 显示类型的方法

  12.9 注意事项

第13章 低级编程

  13.1 unsafe.Sizeof,Alignof和Offsetof

  13.2 unsfae.Pointer

  13.3 示例:深度相等

  13.4 使用cgo调用c代码

  13.5 关于安全的注意事项

猜你喜欢

转载自www.cnblogs.com/revoid/p/9216666.html