《Go 语言编程》笔记

今天花了 2.5 小时看完这本书,总体来说这本书的内容偏浅,拿来入门比较合适——当然对于我这种从不看书、只靠文档 + 实践学习语言的来说,一些基础的知识点还是有必要补补的。看书的过程简单记了下笔记,太基础的直接跳过了,只记了部分我认为比较关键的知识点。全书最核心的部分当数第四章——并发编程。

@author migege@github
@version 170622:1

语言特点

  • 并发与分布式
  • 软件工程
  • 编程哲学

基础

多返回值

func getName() (firstName, middleName, lastName, nickName string) {
    firstName = "A"
    middleName = "B"
    lastName = "C"
    nickName = "D"
    return
}

匿名函数和闭包

f := func(x, y int) int {
    return x + y
}

反射

type Bird struct {
    Name string
    LifeExpectance int
}

func main() {
    sparrow := &Bird{"Sparrow", 3}
    s := reflect.ValueOf(sparrow).Elem()
    typeOfT := s.Type()
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface())
    }
}

Cgo

package main

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import "unsafe"

func main() {
    cstr := C.CString("Hello, world!")
    C.puts(cstr)
    C.free(unsafe.Pointer(cstr))
}

工程管理

运行

go run

构建

go build

单元测试

go test

GDB 调试

gdb xxx

调试信息为 DWARFv3,>= gdb1.7

语法

预定义常量

const (
    c0 = iota
    c1 = iota
    c2 = iota
)

枚举

const (
    Sunday = itoa
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    numberOfDays
)

数组切片

cap()len()

goto

竟然支持 goto

defer / panic() / recover()

defer func() {
    if r := recover(); r != nil {
        // do something
    }
}

foo()

passed by value

类型都是值传递

面向对象编程

匿名组合

虚基类

type Job struct {
    Command string
    *log.Logger
}

func (job *Job) Start() {
    job.Log("starting...")
}

非侵入式接口

一个类只需要实现了接口要求的所有函数,就认为这个类实现了该接口。

接口查询

var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
}

类型查询

switch v := arg.(type) {
    case int:
    case string:
    default:
    // ...
}

并发编程

goroutine

go 关键字

并发通信

不要通过共享内存来通信,而应该通过通信来共享内存。

channel

ch <- 1

channel 在被读取前,写入操作是阻塞的。

<- ch

channel 在被写入前,读取操作是阻塞的。

基本语法

var ch chan int
var m map[string]chan bool
ch := make(chan int)

select

select {
    case <- ch1:
    case <- ch2:
    default:
}

缓冲机制

ch := make(chan int, 1024)

即使没有读取方,写入方也可以一直往 channel 里写入,在缓冲区被填满之前都不会阻塞。

超时机制

timeout := make(chan bool, 1)
go func() {
    time.Sleep(1e9)
    timeout <- true
}

select {
    case <- ch:
    // ...
    case <- timeout:
    // timeout
}

channel 可被传递

可以用来实现 pipe。

单向 channel

var ch1 chan<- float64 // 仅写入
var ch2 <-chan int // 仅读取

关闭 channel

close(ch)

x, ok := <-ch

多核并行化

runtime.GOMAXPROCS(runtime.NumCPU())

出让时间片

runtime.Gosched()

同步

同步锁

sync.Mutexsync.RWMutex

var l sync.Mutex
func foo() {
    l.Lock()
    defer l.Unlock()
}

全局唯一性操作

var once sync.Once
once.Do(...)

sync/atomic 子包

func CompareAndSwapUint64(val *unit64, old, new uint64) (swapped bool)

网络编程

Socket 编程

Dial()


### HTTP 编程

```net/http

RPC 编程

rpc.Register()

工程管理

gofmt

godoc

开发工具

gocode

其它

libtask

donate to me

0 Comments

No comments yet.

Leave a Reply