Featured image of post Go

Go

ENV

Proxy

1
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

SumDB

1
go env -w GOSUMDB=off

Tips

切片会导致整个底层数组不能被回收

解决办法是创建新的切片

1
slice = append([]T{}, slice[1:]...)

判断切片不为空

1
2
3
4
-if len(slice) != 0 {
+if len(slice) > 0 {
    ...
}

defer 与命名返回值

如果在 defer 语句中或过程中(例如 defer wg.Wait())修改返回值,需要使用命名返回值

1
2
3
4
5
6
func example() (result int) {
    defer func() {
        result += 10 // 修改命名返回值
    }()
    return 5 // 返回值为 5,但在 defer 中被修改为 15
}

接口实现的编译期检查

1
2
3
// Ensure that *Test implements the Tester interface.
// This will cause a compile-time error if it does not.
var _ Tester = (*Test)(nil)

可以间接表明这个结构体实现了某个接口

指向指针的指针

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import "fmt"

// Tt 是一个简单的结构体,包含一个字段 A
type Tt struct {
	A string
}

// NewTtPtr 通过传入 *Tt 的指针,创建并返回一个新的 Tt 实例
func NewTtPtr(t **Tt) {
	*t = &Tt{A: "created via pointer to pointer"}
}

// SetTt 从一个已有的 Tt 的指针中修改其内容
//
// 解引用 t,如果是 nil,会 panic
func SetTt(t *Tt) {
	*t = Tt{A: "modified via pointer"}
}

func main() {
	// 示例:通过指针的指针创建一个新的结构体指针
	var t *Tt
	NewTtPtr(&t)
	fmt.Printf("t = %#+v\n", t)
	// t = &main.Tt{A:"created via pointer to pointer"}

	// 示例:通过指针修改已有结构体的值
	var tt Tt
	SetTt(&tt)
	fmt.Printf("tt = %#+v\n", tt)
	// tt = main.Tt{A:"modified via pointer"}

	// 错误示例:传入一个 nil 的指针,会 panic
	var ttt *Tt
	//SetTt(ttt) // 这里会 panic,因为 ttt 是 nil
	fmt.Printf("ttt = %#+v\n", ttt)
	// ttt = (*main.Tt)(nil)

	// 正确示例:直接创建一个 Tt 实例的指针并传递
	ttt = &Tt{A: "created directly"}
	fmt.Printf("ttt = %#+v\n", ttt)
	// ttt = &main.Tt{A:"created directly"}
	SetTt(ttt)
	fmt.Printf("ttt = %#+v\n", ttt)
	// ttt = &main.Tt{A:"modified via pointer"}
}
Licensed under CC BY-NC-SA 4.0