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
replace github.com/clipperhouse/displaywidth => github.com/clipperhouse/displaywidth v0.3.1

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

解决办法是创建新的切片

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
4
5
6
7
8
// Ensure that *Test implements the Tester interface.
// This will cause a compile-time error if it does not.
var _ Tester = (*Test)(nil)

// Same as above, but using a function to return the interface type.
func NewTest() Tester {
    return &Test{}
}

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

指向指针的指针

 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"

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

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

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

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

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

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

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