Go 语言速查表
这是一个 Go 语言的快速参考手册,包含常用语法和代码片段。
基本结构
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
变量声明
var name string = "张三"
var age = 25
city := "北京"
const PI = 3.14159
var (
x int
y string
z bool
)
基本类型
| 类型 | 说明 |
|---|---|
bool | 布尔值 |
string | 字符串 |
int, int8, int16, int32, int64 | 整数 |
uint, uint8, uint16, uint32, uint64 | 无符号整数 |
float32, float64 | 浮点数 |
complex64, complex128 | 复数 |
byte | uint8 别名 |
rune | int32 别名,Unicode 码点 |
控制结构
条件语句
if x > 0 {
fmt.Println("正数")
} else if x < 0 {
fmt.Println("负数")
} else {
fmt.Println("零")
}
if err := doSomething(); err != nil {
log.Fatal(err)
}
Switch
switch day {
case 1, 2, 3, 4, 5:
fmt.Println("工作日")
case 6, 7:
fmt.Println("周末")
default:
fmt.Println("无效")
}
switch {
case score >= 90:
fmt.Println("优秀")
case score >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
循环
for i := 0; i < 10; i++ {
fmt.Println(i)
}
for key, value := range map {
fmt.Println(key, value)
}
for {
if condition {
break
}
}
for condition {
}
数组和切片
arr := [3]int{1, 2, 3}
arr := [...]int{1, 2, 3}
slice := []int{1, 2, 3}
slice := make([]int, 5)
slice := make([]int, 5, 10)
slice = append(slice, 4, 5)
slice = append(slice, anotherSlice...)
copy(dst, src)
slice[1:3]
slice[:3]
slice[1:]
Map
m := make(map[string]int)
m := map[string]int{"a": 1, "b": 2}
m["key"] = value
delete(m, "key")
value, exists := m["key"]
if exists {
fmt.Println(value)
}
for key, value := range m {
fmt.Println(key, value)
}
结构体
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
p := Person{Name: "张三", Age: 25}
p := &Person{Name: "张三"}
p := new(Person)
p.Name = "李四"
方法
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
r := Rectangle{Width: 10, Height: 5}
area := r.Area()
r.Scale(2)
接口
type Writer interface {
Write([]byte) (int, error)
}
type Reader interface {
Read([]byte) (int, error)
}
type ReadWriter interface {
Reader
Writer
}
var w Writer = &MyWriter{}
if v, ok := w.(Closer); ok {
v.Close()
}
switch v := i.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
}
错误处理
import "errors"
err := errors.New("错误信息")
if err != nil {
return err
}
result, err := someFunction()
if err != nil {
log.Fatal(err)
}
type MyError struct {
Msg string
}
func (e *MyError) Error() string {
return e.Msg
}
Goroutine
go func() {
fmt.Println("并发执行")
}()
go myFunction()
Channel
ch := make(chan int)
ch := make(chan int, 10)
ch <- value
value := <-ch
value, ok := <-ch
close(ch)
for value := range ch {
fmt.Println(value)
}
select {
case msg := <-ch1:
fmt.Println(msg)
case ch2 <- value:
fmt.Println("发送成功")
case <-time.After(time.Second):
fmt.Println("超时")
default:
fmt.Println("无操作")
}
Context
ctx := context.Background()
ctx := context.TODO()
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
defer cancel()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
ctx := context.WithValue(ctx, "key", "value")
value := ctx.Value("key")
select {
case <-ctx.Done():
return ctx.Err()
default:
}
Sync 包
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
var rwmu sync.RWMutex
rwmu.RLock()
defer rwmu.RUnlock()
rwmu.Lock()
defer rwmu.Unlock()
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
}()
wg.Wait()
var once sync.Once
once.Do(func() {
})
var m sync.Map
m.Store("key", "value")
value, ok := m.Load("key")
m.Delete("key")
字符串操作
import "strings"
strings.Contains("hello", "ell")
strings.HasPrefix("hello", "he")
strings.HasSuffix("hello", "lo")
strings.Index("hello", "l")
strings.ToLower("HELLO")
strings.ToUpper("hello")
strings.Split("a,b,c", ",")
strings.Join([]string{"a", "b"}, "-")
strings.Replace("hello", "l", "L", -1)
strings.TrimSpace(" hello ")
strings.Fields("hello world")
strings.Repeat("a", 5)
格式化
fmt.Printf("字符串: %s\n", "hello")
fmt.Printf("整数: %d\n", 123)
fmt.Printf("浮点: %.2f\n", 3.14)
fmt.Printf("布尔: %t\n", true)
fmt.Printf("类型: %T\n", x)
fmt.Printf("值: %v\n", x)
fmt.Printf("详细: %+v\n", struct)
fmt.Printf("完整: %#v\n", x)
fmt.Printf("十六进制: %x\n", 255)
fmt.Printf("二进制: %b\n", 10)
fmt.Printf("指针: %p\n", &x)
JSON
import "encoding/json"
data, _ := json.Marshal(obj)
data, _ := json.MarshalIndent(obj, "", " ")
var obj MyStruct
json.Unmarshal(data, &obj)
type User struct {
Name string `json:"name"`
Age int `json:"age,omitempty"`
Email string `json:"email"`
}
文件操作
import "os"
file, _ := os.Open("file.txt")
defer file.Close()
file, _ := os.Create("file.txt")
defer file.Close()
data, _ := os.ReadFile("file.txt")
os.WriteFile("file.txt", data, 0644)
os.Remove("file.txt")
os.Rename("old.txt", "new.txt")
os.Mkdir("dir", 0755)
os.MkdirAll("a/b/c", 0755)
os.RemoveAll("dir")
HTTP 客户端
import "net/http"
resp, _ := http.Get("https://example.com")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
resp, _ := http.Post(url, "application/json", body)
resp, _ := http.PostForm(url, url.Values{"key": {"value"}})
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer token")
client := &http.Client{Timeout: 10 * time.Second}
resp, _ := client.Do(req)
HTTP 服务端
import "net/http"
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello")
})
http.ListenAndServe(":8080", nil)
mux := http.NewServeMux()
mux.HandleFunc("/api", handler)
http.ListenAndServe(":8080", mux)
时间处理
import "time"
now := time.Now()
t, _ := time.Parse("2006-01-02", "2024-01-01")
t, _ := time.ParseInLocation("2006-01-02", "2024-01-01", time.Local)
fmt.Println(now.Format("2006-01-02 15:04:05"))
tomorrow := now.Add(24 * time.Hour)
duration := now.Sub(t)
time.Sleep(time.Second)
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
}
timer := time.NewTimer(time.Second)
<-timer.C
常用命令
go run main.go # 运行
go build # 编译
go test # 测试
go test -v # 详细测试
go test -cover # 覆盖率
go fmt # 格式化
go vet # 静态检查
go mod init # 初始化模块
go mod tidy # 整理依赖
go get package # 获取依赖
go get -u package # 更新依赖
go doc # 文档
go env # 环境变量
go version # 版本
常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
nil pointer dereference | 空指针访问 | 检查指针是否为 nil |
index out of range | 数组越界 | 检查索引范围 |
invalid memory address | 内存地址无效 | 检查指针和引用 |
deadlock | 死锁 | 检查 channel 和锁 |
goroutine leak | goroutine 泄漏 | 确保 goroutine 能退出 |
性能优化
import "sync"
var pool = sync.Pool{
New: func() interface{} {
return new(MyStruct)
},
}
obj := pool.Get().(*MyStruct)
defer pool.Put(obj)
import "strings"
var b strings.Builder
b.WriteString("hello")
b.WriteString(" world")
result := b.String()
import "strconv"
strconv.Itoa(123)
strconv.Atoi("123")
测试
import "testing"
func TestAdd(t *testing.T) {
result := Add(1, 2)
if result != 3 {
t.Errorf("Add(1, 2) = %d; want 3", result)
}
}
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(1, 2)
}
}
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
常用第三方库
| 库 | 用途 |
|---|---|
github.com/gin-gonic/gin | Web 框架 |
gorm.io/gorm | ORM |
github.com/go-redis/redis | Redis 客户端 |
github.com/lib/pq | PostgreSQL 驱动 |
go.mongodb.org/mongo-driver | MongoDB 驱动 |
github.com/golang-jwt/jwt | JWT 认证 |
github.com/spf13/viper | 配置管理 |
github.com/uber-go/zap | 日志 |
github.com/stretchr/testify | 测试工具 |