读书笔记golang

go grammer

  1. the standard Go compiler and gccgo both don't allow local variables declared but not used. Package-level variables have no such limit. If a local variable is only ever used as destination values, it will also be viewed as unused.

  2. Overflows are not allowed for typed constant values but are allowed for non-constant and untyped constant values.
    • Non-constant integer values can be converted to strings.
    • Non-constant floating-point and integer values can be explicitly converted to any other floating-point and integer types.
    • Non-constant complex values can be explicitly converted to any other complex types.
  3. The name of the folder of a package is not required to be the same as the package name. However, for a library package, it will make package users confused if the name of the package is different from the name of the folder of the package.

    • A package-level variable is initialized after all of its depended variables.
    • All package-level variables declared in a package are initialized before any init function declared in the same package is invoked.
    • All init functions in all involved packages in a program will be invoked sequentially. An init function in an importing package will be invoked after all the init functions declared in the dependency packages of the importing package for sure. All init functions will be invoked before invoking the main entry function.
  4. The expressions enclosed within the body of an anonymous function call, whether the call is a general call or a deferred/goroutine call, will not be evaluated at the moment when the anonymous function call is invoked.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package main

    import "fmt"

    func main() {
    func() {
    for i := 0; i < 3; i++ {
    defer fmt.Println("a:", i)
    }
    }()
    fmt.Println()
    func() {
    for i := 0; i < 3; i++ {
    defer func() {
    fmt.Println("b:", i)
    }()
    }
    }()
    }

    output is: a: 2 a: 1 a: 0

            b: 3
            b: 3
            b: 3

    to get b: 2, b: 1, b: 0

    1
    2
    3
    4
    5
    6
    7
    func() {
    for i := 0; i < 3; i++ {
    defer func(i int) {
    fmt.Println("b:", i)
    }(i)
    }
    }()

go 数组大小不能超过2GB

需要针对数组元素的类型大小计算数组的最大长度范围 ([]uint8 最大2GB, []uint16 最大1GB,以此类推),但是 []struct{} 数组的长度可以超过2GB

goroutine

  1. 首先系统级的线程创建会创建默认大小的栈(一般默认可能为2Mb),主要用于保存递归函数调用的参数以及局部变量,默认大小的栈存在可能空间浪费或者栈不足的问题;而goroutine采用可以动态增减的栈,初始创建栈大小为(2kb或者4kb),根据需要动态增减(主流实现的栈大小可以达到1gb)

阻塞线程,延迟退出

  1. select{}
  2. for {}
  3. <- make(chan bool)

如果是main函数线程阻塞,正常退出需要调用os.Exit(0)进行退出

生成cgo中间文件

go tool cgo yourfile.go 会生成一个_obj目录包含相关的中间文件

go生成c函数,用于c语言调用

go build -buildmode=c-archive -o sum.a sum.go 将sum.go中的c导出函数生成sum.a以及sum.h文件

defer & panic & recover

defer|panic|recover

  • defer

A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns.

  1. A deferred function's arguments are evaluated when the defer statement is evaluated.
  2. Deferred function calls are executed in Last In First Out order after the surrounding function returns.
  3. Deferred functions may read and assign to the returning function's named return values; deferred functions can modify named return values.
  • recover
  1. Recover is only useful inside deferred functions. During normal execution, a call to recover will return nil and have no other effect.
  2. When panic is called, it immediately stops execution of the current function and begins unwinding the stack of the goroutine, running any deferred functions along the way; Because the only code that runs while unwinding is inside deferred functions, recover is only useful inside deferred functions

channel

  1. nil channel
  • A send to a nil channel blocks forever
  • A receive from a nil channel blocks forever
  • A send to a closed channel panics
  • A receive from a closed channel returns the zero value immediately

cocurrency vs parallel

  1. cocurrency is about dealing with lots of things at once.
  2. parrallel is about doing lots of things at once.

nil interface

type interface ==> T, V keep in mind that if any concrete value has been stored in the interface, the interface will not be nil

assignment

  1. In a short variable declaration, all items at the left of the := sign must pure identifiers. This means some other assignable items, which will be introduced in other articles, can't appear at the left of :=. These items include qualified identifiers, container elements, pointer dereferences and struct field selectors.

slice operations

  1. clone
    1
    clone := append(s[:0:0], s...)

reset some contiguous elements in array or slice

  • memcls(following range for will optimized by go compiler to memcls internal call)
    1
    2
    3
    for i := range a {
    a[i] = t0
    }

efficiently and perfectly clone a slice

1
clone := append(a[:0:0], a...)

cgo 相关

  1. cgo中间文件生成 cgo中间文件

  2. cgo调用流程 cgo调用流程

interface conclusion

  1. interface provide:
  • generic algorithms
  • hidden implementation
  • interception points
  1. implicit satisfication
  • break dependencies
  1. type assertion
  • to extend behaviors
  • to classify errors
  • to maintain compatibility

module

  1. list current module dependency go list -m all and go list -m -versions thepackage

  2. clean unused dependency go mod tidy

-------------本文结束感谢您的阅读-------------