1. 统计耗时
- 使用
defer
关键字和TrackTime
函数来跟踪函数执行时间。
go
复制代码
func TrackTime(pre time.Time) time.Duration {
elapsed := time.Since(pre)
fmt.Println("elapsed:", elapsed)
return elapsed
}
func TestTrackTime(t *testing.T) {
defer TrackTime(time.Now())
time.Sleep(500 * time.Millisecond)
}
2 资源清理
go
复制代码
func setupTeardown() func() {
fmt.Println("Run initialization")
return func() {
fmt.Println("Run cleanup")
}
}
func main() {
defer setupTeardown()()
fmt.Println("Main function called")
}
3. 预先分配切片
go
复制代码
// 而不是这样
a := make([]int, 10)
a[0] = 1
// 这样使用
b := make([]int, 0, 10)
b = append(b, 1)
4. 链式调用
- 修改函数接收者,返回修改后的对象本身,实现链式调用。
go
复制代码
type Person struct {
Name string
Age int
}
func (p *Person) AddAge() *Person {
p.Age++
return p
}
func (p *Person) Rename(name string) *Person {
p.Name = name
return p
}
5. Go 1.20支持将切片解析为数组或数组指针
go
复制代码
func Test(t *testing.T) {
a := []int{0, 1, 2, 3, 4, 5}
b := [3]int(a[0:3])
fmt.Println(b) // [0 1 2]
}
6. 使用_ import进行包初始化
go
复制代码
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
)
7. 使用点.操作符导入包
go
复制代码
package main
import (
"fmt"
. "math"
)
func main() {
fmt.Println(Pi) // 3.141592653589793
fmt.Println(Sin(Pi/2)) // 1
}
8. Go 1.20起可以将多个错误包装成一个错误
- 使用
errors.Join
函数将多个错误关联起来。
go
复制代码
var (
err1 = errors.New("Error 1st")
err2 = errors.New("Error 2nd")
)
func main() {
err := err1
err = errors.Join(err, err2)
fmt.Println(errors.Is(err, err1)) // true
fmt.Println(errors.Is(err, err2)) // true
}
9. 编译时检查接口的技巧
go
复制代码
var _ Buffer = (*StringBuffer)(nil)
10. 三元运算符
- 利用泛型在Go 1.18中创建类似三元运算符的功能。
go
复制代码
func Ter[T any](cond bool, a, b T "T any") T {
if cond {
return a
}
return b
}
11. 验证接口是否真的为nil的方法
- 使用
reflect.ValueOf(x).IsNil()
来检查接口值是否为nil。
go
复制代码
func IsNil(x interface{}) bool {
if x == nil {
return true
}
return reflect.ValueOf(x).IsNil()
}