跳到主要内容

Go 知识速查表

本页面汇总了 Go 编程中最常用的语法和知识点,方便快速查阅。

数据类型

类型示例说明
int10, -5整数,平台相关(32/64位)
int81008位有符号整数(-128~127)
int16100016位有符号整数
int3210000032位有符号整数
int641000000000064位有符号整数
uint10无符号整数
uint8 / byte2558位无符号整数/字节
uint3210000032位无符号整数
uint641000000000064位无符号整数
float323.1432位浮点数
float643.1415964位浮点数(默认)
complex643+4i64位复数
complex1283+4i128位复数(默认)
booltrue, false布尔值
string"hello"字符串(UTF-8编码)
rune'中'Unicode码点(int32别名)

类型转换

// 数值类型转换
var i int = 10
var f float64 = float64(i) // int -> float64
var u uint = uint(i) // int -> uint

var f2 float64 = 3.14
var i2 int = int(f2) // float64 -> int(截断小数)

// 字符串转换
import "strconv"

// 字符串转整数
n, err := strconv.Atoi("123") // n = 123
n64, err := strconv.ParseInt("123", 10, 64) // base 10, 64位

// 整数转字符串
s := strconv.Itoa(123) // s = "123"
s64 := strconv.FormatInt(123, 10) // base 10

// 字符串转浮点数
f, err := strconv.ParseFloat("3.14", 64)

// 浮点数转字符串
s = strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"

// 字符串与字节/符文切片
bytes := []byte("hello") // 字符串转字节切片
str := string(bytes) // 字节切片转字符串
runes := []rune("你好") // 字符串转符文切片
str = string(runes) // 符文切片转字符串

变量声明

// 完整声明
var name string = "张三"
var age int = 25

// 类型推断
var name = "张三"
var age = 25

// 简短声明(函数内)
name := "张三"
age := 25

// 多个变量
var a, b, c int = 1, 2, 3
a, b, c := 1, 2, 3

// 变量组
var (
name string = "张三"
age int = 25
)

// 零值
var i int // 0
var f float64 // 0
var b bool // false
var s string // ""
var p *int // nil
var slice []int // nil
var m map[string]int // nil

常量

// 单个常量
const Pi = 3.14159
const MaxSize = 100

// 常量组
const (
StatusOK = 200
StatusNotFound = 404
)

// iota 枚举
const (
Red = iota // 0
Green // 1
Blue // 2
)

// iota 位掩码
const (
Read = 1 << iota // 1 (001)
Write // 2 (010)
Execute // 4 (100)
)

// iota 跳过
const (
_ = iota // 跳过 0
KB = 1 << (10 * iota) // 1024
MB // 1048576
GB // 1073741824
)

运算符

算术运算符

+   // 加法
- // 减法
* // 乘法
/ // 除法(整数相除结果为整数)
% // 取模

比较运算符

==  // 等于
!= // 不等于
< // 小于
> // 大于
<= // 小于等于
>= // 大于等于

逻辑运算符

&&  // 逻辑与(短路)
|| // 逻辑或(短路)
! // 逻辑非

位运算符

&   // 按位与
| // 按位或
^ // 按位异或
&^ // 位清除(AND NOT)
<< // 左移
>> // 右移

赋值运算符

=   // 赋值
+= // 加后赋值
-= // 减后赋值
*= // 乘后赋值
/= // 除后赋值
%= // 取模后赋值
&= // 按位与后赋值
|= // 按位或后赋值
^= // 按位异或后赋值
<<= // 左移后赋值
>>= // 右移后赋值

字符串操作

import "strings"

s := "Hello, Go!"

// 基本信息
len(s) // 字符串长度(字节数)

// 查找
strings.Contains(s, "Go") // true
strings.HasPrefix(s, "Hello") // true
strings.HasSuffix(s, "Go!") // true
strings.Index(s, "Go") // 7(首次出现位置)
strings.LastIndex(s, "l") // 3(最后出现位置)

// 转换
strings.ToUpper(s) // "HELLO, GO!"
strings.ToLower(s) // "hello, go!"
strings.Title(s) // "Hello, Go!"
strings.TrimSpace(s) // 去除首尾空白
strings.Trim(s, "!") // 去除指定字符

// 替换
strings.Replace(s, "Go", "World", 1) // 替换1次
strings.ReplaceAll(s, "l", "L") // 替换所有

// 分割与拼接
parts := strings.Split("a,b,c", ",") // ["a", "b", "c"]
strings.Join(parts, "-") // "a-b-c"
strings.SplitN("a,b,c", ",", 2) // 最多分割成2部分

// 其他
strings.Repeat("Go", 3) // "GoGoGo"
strings.Count("hello", "l") // 2

字符串格式化

import "fmt"

// 常用动词
%v // 默认格式
%+v // 结构体时加字段名
%#v // Go语法表示
%T // 类型
%% // 百分号

// 整数
%d // 十进制
%b // 二进制
%o // 八进制
%x // 十六进制(小写)
%X // 十六进制(大写)

// 浮点数
%f // 浮点数
%e // 科学计数法
%g // 自动选择 %f 或 %e

// 字符串
%s // 字符串
%q // 带引号的字符串
%x // 十六进制表示

// 指针
%p // 指针地址

// 宽度与精度
%5d // 宽度5,右对齐
%-5d // 宽度5,左对齐
%05d // 宽度5,前导0
%.2f // 保留2位小数
%8.2f // 宽度8,2位小数

数组与切片

数组

// 声明
var arr [5]int // [0 0 0 0 0]
arr2 := [3]int{1, 2, 3} // [1 2 3]
arr3 := [...]int{1, 2, 3} // 自动推断长度

// 访问与修改
arr[0] = 10
x := arr[0]

// 长度
len(arr)

// 遍历
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}

for i, v := range arr {
fmt.Println(i, v)
}

切片

// 声明与初始化
var s []int // nil 切片
s = make([]int, 5) // 长度5,容量5
s = make([]int, 5, 10) // 长度5,容量10
s = []int{1, 2, 3} // 字面量初始化

// 从数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
s = arr[1:4] // [2 3 4]
s = arr[:3] // [1 2 3]
s = arr[2:] // [3 4 5]
s = arr[:] // [1 2 3 4 5]

// 操作
s = append(s, 6) // 追加元素
s = append(s, 7, 8, 9) // 追加多个
s = append(s, anotherSlice...) // 追加切片

// 复制
copy(dst, src) // 返回复制的元素数

// 长度与容量
len(s) // 长度
cap(s) // 容量

// 截取(共享底层数组)
s2 := s[1:3]

// 遍历
for i, v := range s {
fmt.Println(i, v)
}

// 删除元素(没有内置函数)
// 删除索引 i
s = append(s[:i], s[i+1:]...)
// 删除第一个元素
s = s[1:]
// 删除最后一个元素
s = s[:len(s)-1]

映射(Map)

// 声明与初始化
var m map[string]int // nil map
m = make(map[string]int) // 空 map
m = map[string]int{"a": 1, "b": 2} // 字面量初始化

// 操作
m["key"] = 100 // 设置/添加
value := m["key"] // 获取
value, ok := m["key"] // 获取并检查是否存在

delete(m, "key") // 删除

// 长度
len(m)

// 遍历
for k, v := range m {
fmt.Println(k, v)
}

// 只遍历键
for k := range m {
fmt.Println(k)
}

// 检查键是否存在
if v, ok := m["key"]; ok {
fmt.Println("存在:", v)
}

控制流

if 语句

// 基本形式
if x > 0 {
// ...
}

// 带初始化语句
if err := doSomething(); err != nil {
return err
}

// if-else
if x > 0 {
// ...
} else if x < 0 {
// ...
} else {
// ...
}

switch 语句

// 基本形式
switch x {
case 1:
// ...
case 2, 3:
// ...
default:
// ...
}

// 无表达式(替代 if-else)
switch {
case x > 0:
// ...
case x < 0:
// ...
default:
// ...
}

// 带初始化
switch n := len(s); n {
case 0:
// ...
case 1, 2:
// ...
}

// 类型断言 switch v := i.(type) {
case int:
// v 是 int
case string:
// v 是 string
default:
// v 是 i 的原始类型
}

for 循环

// 标准 for
for i := 0; i < 10; i++ {
// ...
}

// 条件 for(类似 while)
for x < 100 {
// ...
}

// 无限循环
for {
// ...
}

// range 遍历
for i, v := range slice {
// i: 索引, v: 值
}

for k, v := range map {
// k: 键, v: 值
}

for i, c := range string {
// i: 字节索引, c: rune
}

// 忽略索引或值
for _, v := range slice { } // 忽略索引
for i := range slice { } // 忽略值
for range slice { } // 只遍历次数

// break 和 continue
for i := 0; i < 10; i++ {
if i == 5 {
break // 跳出循环
}
if i%2 == 0 {
continue // 跳过本次
}
}

// 带标签的 break/continue
Outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i*j > 4 {
break Outer // 跳出外层循环
}
}
}

函数

函数定义

// 基本函数
func add(a, b int) int {
return a + b
}

// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}

// 命名返回值
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 裸 return,返回命名返回值
}

// 变参函数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
// 调用: sum(1, 2, 3) 或 sum(slice...)

// 函数作为参数
func apply(f func(int) int, x int) int {
return f(x)
}

// 函数作为返回值
func makeMultiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}

defer

// defer 延迟执行,函数返回前执行
func readFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close() // 确保文件关闭

// 处理文件...
return nil
}

// 多个 defer(LIFO 顺序)
func example() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// 输出: 3 2 1
}

// defer 参数立即求值
func example() {
i := 0
defer fmt.Println(i) // 输出 0,不是 1
i++
}

函数式选项模式

type Option func(*Server)

func WithPort(port int) Option {
return func(s *Server) { s.port = port }
}

func NewServer(host string, opts ...Option) *Server {
s := &Server{host: host, port: 8080} // 默认值
for _, opt := range opts {
opt(s)
}
return s
}

// 使用
s := NewServer("localhost", WithPort(9000))

中间件模式

type Middleware func(http.Handler) http.Handler

func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Request: %s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}

// 使用
handler := LoggingMiddleware(http.DefaultServeMux)

闭包

func counter() func() int {
count := 0
return func() int {
count++
return count
}
}

c := counter()
fmt.Println(c()) // 1
fmt.Println(c()) // 2

// 注意闭包变量捕获
for i := 0; i < 3; i++ {
i := i // 必须创建新变量
go func() { fmt.Println(i) }()
}

结构体

// 定义
type Person struct {
Name string
Age int
}

// 创建实例
p := Person{Name: "张三", Age: 25}
p := Person{"张三", 25} // 按字段顺序
p := new(Person) // 返回 *Person,字段为零值
p := &Person{Name: "张三"} // 返回 *Person

// 访问字段
p.Name = "李四"
age := p.Age

// 匿名结构体
p := struct {
Name string
Age int
}{
Name: "张三",
Age: 25,
}

// 嵌套结构体
type Address struct {
City string
Street string
}

type Person struct {
Name string
Address Address // 嵌入结构体
}

p := Person{
Name: "张三",
Address: Address{
City: "北京",
Street: "长安街",
},
}

// 嵌入类型(匿名字段)
type Employee struct {
Person // 嵌入 Person,继承其方法
Salary int
}

e := Employee{
Person: Person{Name: "张三"},
Salary: 5000,
}
fmt.Println(e.Name) // 直接访问嵌入类型的字段

// 函数式选项模式
type Server struct {
host string
port int
}

type Option func(*Server)

func WithPort(port int) Option {
return func(s *Server) { s.port = port }
}

func NewServer(host string, opts ...Option) *Server {
s := &Server{host: host, port: 8080} // 默认值
for _, opt := range opts {
opt(s)
}
return s
}

// 使用
s := NewServer("localhost", WithPort(9000))

方法

// 值接收者
type Rectangle struct {
Width, Height float64
}

func (r Rectangle) Area() float64 {
return r.Width * r.Height
}

// 指针接收者
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}

// 使用
rect := Rectangle{10, 5}
area := rect.Area() // 值接收者
rect.Scale(2) // 指针接收者,修改原值

// 方法规则:
// - 值接收者:方法内不能修改原值
// - 指针接收者:方法内可以修改原值
// - 值类型可以调用指针接收者方法(Go 自动取地址)
// - 指针类型可以调用值接收者方法(Go 自动解引用)

接口

// 定义接口
type Writer interface {
Write(p []byte) (n int, err error)
}

type Reader interface {
Read(p []byte) (n int, err error)
}

// 组合接口
type ReadWriter interface {
Reader
Writer
}

// 实现接口(隐式实现)
type MyWriter struct{}

func (m MyWriter) Write(p []byte) (n int, err error) {
return len(p), nil
}

// 空接口(可存储任意类型)
var i interface{}
i = 42
i = "hello"
i = struct{ X int }{10}

// 类型断言
v, ok := i.(int) // 安全断言
v := i.(int) // 不安全,失败会 panic

// 类型 switch
switch v := i.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
default:
fmt.Printf("unknown: %T\n", v)
}

并发

Goroutine

// 启动 goroutine
go functionName()
go func() {
// 匿名函数
}()

// 等待 goroutine 完成
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// 工作...
}()
wg.Wait()

Channel

// 创建 channel
ch := make(chan int) // 无缓冲 channel
ch := make(chan int, 10) // 缓冲 channel

// 发送与接收
ch <- v // 发送
v := <-ch // 接收

// 关闭 channel
close(ch)

// 检查 channel 是否关闭
v, ok := <-ch
if !ok {
// channel 已关闭
}

// range 遍历 channel
for v := range ch {
// 处理 v,直到 channel 关闭
}

// select 多路复用
select {
case v1 := <-ch1:
// 从 ch1 接收
case v2 := <-ch2:
// 从 ch2 接收
case ch3 <- v3:
// 向 ch3 发送
default:
// 无操作可执行时
}

// 超时控制
select {
case result := <-ch:
// 处理结果
case <-time.After(3 * time.Second):
// 超时
}

// 非阻塞操作
select {
case ch <- v:
// 发送成功
default:
// 发送失败,channel 已满
}

错误处理

// 创建错误
err := errors.New("something went wrong")
err := fmt.Errorf("wrapped error: %w", originalErr)

// 错误包装与解包
if errors.Is(err, targetErr) {
// err 链中包含 targetErr
}

var customErr *MyError
if errors.As(err, &customErr) {
// err 链中包含 *MyError 类型
}

// 自定义错误类型
type NotFoundError struct {
Resource string
ID string
}

func (e *NotFoundError) Error() string {
return fmt.Sprintf("%s %s not found", e.Resource, e.ID)
}

// panic 与 recover
func mayPanic() {
panic("something went wrong")
}

func safeCall() {
defer func() {
if r := recover(); r != nil {
// 处理 panic
fmt.Println("Recovered:", r)
}
}()
mayPanic()
}

常用标准库

fmt - 格式化 I/O

import "fmt"

fmt.Print("hello")
fmt.Println("hello")
fmt.Printf("hello %s", "world")
fmt.Sprintf("hello %s", "world") // 返回字符串
fmt.Fprint(w, "hello") // 写入 io.Writer
fmt.Fscan(r, &x) // 从 io.Reader 读取

os - 操作系统接口

import "os"

// 文件操作
file, err := os.Open("file.txt")
file, err := os.Create("file.txt")
file, err := os.OpenFile("file.txt", os.O_RDWR|os.O_CREATE, 0644)

data, err := os.ReadFile("file.txt")
err := os.WriteFile("file.txt", data, 0644)

// 环境变量
value := os.Getenv("HOME")
os.Setenv("KEY", "value")

// 进程
os.Exit(1)

io - I/O 原语

import "io"

// 读取全部
content, err := io.ReadAll(reader)

// 复制
n, err := io.Copy(dst, src)
n, err := io.CopyN(dst, src, 100)

// 限制读取
limitedReader := io.LimitReader(r, 100)

// 多路写入
multiWriter := io.MultiWriter(w1, w2)

bufio - 缓冲 I/O

import "bufio"

// 读取
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
}

reader := bufio.NewReader(file)
line, err := reader.ReadString('\n')

// 写入
writer := bufio.NewWriter(file)
writer.WriteString("hello")
writer.Flush()

time - 时间处理

import "time"

// 获取时间
now := time.Now()
t := time.Date(2024, 1, 1, 0, 0, 0, 0, time.Local)

// 解析与格式化
t, err := time.Parse("2006-01-02", "2024-01-01")
str := now.Format("2006-01-02 15:04:05")

// 时间运算
duration := time.Hour + 30*time.Minute
later := now.Add(duration)
diff := later.Sub(now)

// 睡眠
time.Sleep(1 * time.Second)

// 定时器
timer := time.NewTimer(1 * time.Second)
<-timer.C

ticker := time.NewTicker(1 * time.Second)
for t := range ticker.C {
// 每秒执行
}

strings - 字符串处理

import "strings"

strings.Contains(s, substr)
strings.HasPrefix(s, prefix)
strings.HasSuffix(s, suffix)
strings.Index(s, substr)
strings.Split(s, sep)
strings.Join(slice, sep)
strings.TrimSpace(s)
strings.ToLower(s)
strings.ToUpper(s)
strings.ReplaceAll(s, old, new)

strconv - 字符串转换

import "strconv"

// 字符串转数字
i, err := strconv.Atoi("123")
i64, err := strconv.ParseInt("123", 10, 64)
f, err := strconv.ParseFloat("3.14", 64)
b, err := strconv.ParseBool("true")

// 数字转字符串
s := strconv.Itoa(123)
s = strconv.FormatInt(123, 10)
s = strconv.FormatFloat(3.14, 'f', 2, 64)
s = strconv.FormatBool(true)

encoding/json - JSON 处理

import "encoding/json"

// 编码(结构体转 JSON)
data, err := json.Marshal(obj)
data, err := json.MarshalIndent(obj, "", " ")

// 解码(JSON 转结构体)
err := json.Unmarshal(data, &obj)

// 流式处理
encoder := json.NewEncoder(writer)
err := encoder.Encode(obj)

decoder := json.NewDecoder(reader)
err := decoder.Decode(&obj)

net/http - HTTP 服务

import "net/http"

// 处理函数
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}

// 注册路由
http.HandleFunc("/", handler)

// 启动服务
http.ListenAndServe(":8080", nil)

// 使用自定义 ServeMux
mux := http.NewServeMux()
mux.HandleFunc("/", handler)
mux.HandleFunc("/api/", apiHandler)
http.ListenAndServe(":8080", mux)

database/sql - 数据库操作

import "database/sql"
import _ "github.com/go-sql-driver/mysql" // 导入驱动

// 连接数据库
db, err := sql.Open("mysql", "user:pass@tcp(127.0.0.1:3306)/dbname")
defer db.Close()

// 验证连接
err = db.Ping()

// 连接池配置
db.SetMaxOpenConns(25) // 最大连接数
db.SetMaxIdleConns(10) // 最大空闲连接
db.SetConnMaxLifetime(5 * time.Minute)
db.SetConnMaxIdleTime(2 * time.Minute)

// 查询单行
var name string
err = db.QueryRow("SELECT name FROM users WHERE id = ?", id).Scan(&name)
if err == sql.ErrNoRows {
// 没有找到记录
}

// 查询多行
rows, err := db.Query("SELECT id, name FROM users WHERE age > ?", minAge)
defer rows.Close()
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
}

// 插入数据
result, err := db.Exec("INSERT INTO users (name) VALUES (?)", "张三")
id, _ := result.LastInsertId()

// 更新数据
result, err := db.Exec("UPDATE users SET name = ? WHERE id = ?", "李四", id)
affected, _ := result.RowsAffected()

// 预处理语句
stmt, err := db.Prepare("SELECT name FROM users WHERE id = ?")
defer stmt.Close()
var name string
err = stmt.QueryRow(id).Scan(&name)

// 事务处理
tx, err := db.Begin()
defer tx.Rollback() // 如果已提交,回滚无效
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, fromID)
_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, toID)
err = tx.Commit()

// NULL 值处理
var nullName sql.NullString
err = db.QueryRow("SELECT name FROM users WHERE id = ?", id).Scan(&nullName)
if nullName.Valid {
fmt.Println(nullName.String)
}

常见模式

单例模式

type singleton struct {
data string
}

var (
instance *singleton
once sync.Once
)

func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{data: "initialized"}
})
return instance
}

工作池

func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
// 处理 job
results <- j * 2
}
}

func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)

// 启动 3 个 worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}

// 发送 9 个 job
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)

// 收集结果
for a := 1; a <= 9; a++ {
<-results
}
}

管道模式

func generator(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}

func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}

func main() {
in := generator(2, 3, 4)
out := square(in)

for n := range out {
fmt.Println(n)
}
}

反射

基本操作

import "reflect"

// 获取类型信息
t := reflect.TypeOf(x)
t.Name() // 类型名
t.Kind() // 类型种类
t.Size() // 大小

// 获取值信息
v := reflect.ValueOf(x)
v.Type() // 类型
v.Kind() // 种类
v.Interface() // 转回 interface{}

// 修改值(必须传指针)
v := reflect.ValueOf(&x).Elem()
if v.CanSet() {
v.SetInt(100)
v.SetString("hello")
}

结构体操作

// 遍历字段
t := reflect.TypeOf(s)
v := reflect.ValueOf(s)

for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
fmt.Printf("%s: %v\n", field.Name, value)
}

// 获取特定字段
field, _ := t.FieldByName("Name")
value := v.FieldByName("Name")

// 获取结构体标签
tag := field.Tag.Get("json")

方法操作

// 遍历方法
t := reflect.TypeOf(s)
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
fmt.Println(method.Name, method.Type)
}

// 调用方法
v := reflect.ValueOf(s)
method := v.MethodByName("MethodName")
results := method.Call([]reflect.Value{
reflect.ValueOf(arg1),
reflect.ValueOf(arg2),
})

Kind 类型

const (
Invalid Kind = iota
Bool
Int, Int8, Int16, Int32, Int64
Uint, Uint8, Uint16, Uint32, Uint64
Float32, Float64
Complex64, Complex128
Array, Chan, Func, Interface
Map, Pointer, Slice, String, Struct
)

工具命令

# 运行
go run main.go
go run .

# 构建
go build
go build -o myapp

# 测试
go test
go test -v # 详细输出
go test -cover # 覆盖率
go test -race # 竞态检测

# 格式化
go fmt ./...

# 检查
go vet ./...

# 依赖管理
go mod init module-name
go mod tidy
go mod download
go mod vendor

# 文档
go doc package
go doc package.Function
godoc -http=:6060 # 启动文档服务器

# 其他
go clean # 清理构建产物
go env # 查看环境变量
go version # 查看版本

性能优化技巧

  1. 使用 strings.Builder 进行字符串拼接
  2. 预分配切片容量避免重新分配
  3. 使用 sync.Pool 复用对象
  4. 避免在热点路径使用反射
  5. 使用 bufio 进行批量 I/O 操作
  6. 合理使用 goroutine,避免过多并发
  7. 使用 pprof 进行性能分析

Go 1.24+ 新特性速查

泛型类型别名

// 泛型类型别名(Go 1.24+)
type List[T any] = []T
type Set[K comparable] = Map[K, bool]

// 必须显式声明类型参数
type G[P Constraint] = pkg1.G[P] // ✅ 正确
// type G = pkg1.G // ❌ 错误

weak.Pointer 弱指针

import "weak"

// 创建弱指针
wp := weak.Make(obj)

// 获取实际对象(可能为 nil)
if v := wp.Value(); v != nil {
// 对象仍然存活
}

runtime.AddCleanup 清理函数

// 替代 SetFinalizer 的现代方案
runtime.AddCleanup(obj, func(arg ArgType) {
// 清理逻辑
}, arg)

// 优点:
// - 不阻止内存回收
// - 安全处理循环引用
// - 支持多个清理函数

基准测试 b.Loop

// Go 1.24+ 推荐方式
func BenchmarkNew(b *testing.B) {
for b.Loop() {
// 测试代码
}
}

// 传统方式
func BenchmarkOld(b *testing.B) {
for i := 0; i < b.N; i++ {
// 测试代码
}
}

Swiss Tables Map

Go 1.24 内置 map 使用 Swiss Tables 实现,性能提升 2-3%:

  • 自动启用,无需代码修改
  • 更快的查找和插入
  • 更低的 CPU 开销
  • 禁用方式:GOEXPERIMENT=noswissmap

synctest 测试包(实验性)

// 测试并发代码
synctest.Run(func() {
// time 包使用假时钟
done := make(chan struct{})
go func() {
time.Sleep(1 * time.Second)
close(done)
}()

synctest.Wait() // 等待所有 goroutine 阻塞

// 安全验证状态
})

// 启用:go test -tags=synctest

参考资源