[Golang] 学习笔记
- Go语言圣经 https://golang-china.github.io/gopl-zh/index.html
- Go语言设计与实现 https://draveness.me/golang/
- Go语言高级编程 https://chai2010.cn/advanced-go-programming-book/index.html
指针
要明白指针,需要知道几个概念:指针地址、指针类型、指针取值
在变量名前面添加&操作符(前缀)来获取变量的内存地址(取地址操作)
- & 取地址操作
- * 取值操作
变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址。
str := "hello world"
// 对字符串取地址, ptr类型为*string
ptr := &str	// ptr为指针变量
fmt.Printf("ptr typr is : %T\n ", ptr)  // ptr typr is : *string
// 打印ptr的指针地址
fmt.Printf("address: %p\n", ptr) // address: 0x14000112020
// 对指针进行取值操作
value := *ptr
fmt.Printf("value type: %T\n", value) // value type: string
// 指针取值后就是指向变量的值
fmt.Printf("value: %s\n", value) // value: hello world
变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
- 对变量进行取地址操作使用&操作符 ,可以获得这个变量的指针变量。
- 指针变量的值是指针地址。
- 对指针变量进行取值操作使用*操作符,可以获得指针变量指向的原变量的值
x := 1
p := &x                       // 取地址操作
fmt.Printf("type is : %T", p) // 指针变量 type is : *int
fmt.Println(*p)               // 取值操作 "1"
*p = 2                        //  修改指针指向的值
fmt.Println(x)                // "2"
函数、闭包、递归
匿名函数
// 具名函数
func Add(a, b int) int {
    return a+b
}
// 匿名函数
var Add = func(a, b int) int {
    return a+b
}
匿名函数可赋值给变量,做为结构字段,或者在 channel 里传送
package main
func main() {
    // --- function variable ---
    fn := func() { println("Hello, World!") }
    fn()
  
    // --- function collection ---
    fns := [](func(x int) int){
        func(x int) int { return x + 1 },
        func(x int) int { return x + 2 },
    }
    println(fns[0](100))
    // --- function as field ---
    d := struct {
        fn func() string
    }{
        fn: func() string { return "Hello, World!" },
    }
    println(d.fn())
    // --- channel of function ---
    fc := make(chan func() string, 2)
    fc <- func() string { return "Hello, World!" }
    println((<-fc)())
}
defer
defer语句被用于预定对一个函数的调用。可以把这类被defer语句调用的函数称为延迟函数。
作用:
- 释放占用的资源
- 捕捉处理异常