Appearance
Go 速记表
基础语法
Hello World & 注释
// Hello Worldpackage mainimport "fmt"func main() { fmt.Println("Hello, World!")}// 单行注释/* 多行注释 可以换行 */// Package 文档注释// 紧贴 package 声明上方输入输出
package mainimport "fmt"func main() { // 输出 fmt.Println("Hello, World!") fmt.Printf("Name: %s, Age: %d\n", "Alice", 25) // 输入 var name string var age int fmt.Print("Enter your name: ") fmt.Scanln(&name) fmt.Print("Enter your age: ") fmt.Scanln(&age) fmt.Printf("Hello, %s!\n", name)}变量与常量
声明方式
var name string = "Alice"var age int = 25var x int // 零值初始化// 短声明(仅函数内)count := 10name := "Bob"// 多变量声明var ( x int = 1 y int = 2)a, b := 1, 2常量
const PI = 3.14const ( StatusOK = 200 StatusNotFound = 404)// iota 枚举const ( Sunday = iota // 0 Monday // 1 Tuesday // 2)作用域
var globalVar = "global" // 包级作用域func example() { localVar := "local" // 函数作用域 if true { blockVar := "block" // 块作用域 }}数据类型
基本类型
// 整数int int8 int16 int32 int64uint uint8 uint16 uint32 uint64 uintptr// 浮点数float32 float64// 复数complex64 complex128// 其他boolbyte // uint8 别名rune // int32 别名,表示 Unicode 码点string复合类型
// 数组var arr [5]int// 切片var slice []int// 映射var m map[string]int// 结构体type Person struct { Name string Age int}// 指针var p *int类型转换
var i int = 42var f float64 = float64(i)var u uint = uint(f)// 字符串转换str := strconv.Itoa(i)num, err := strconv.Atoi(str)f, err := strconv.ParseFloat("3.14", 64)零值
// 未初始化变量的默认值0 // 数字类型false // bool"" // stringnil // 指针、切片、映射、通道、函数运算符
算术运算符
+ - * / %++ -- // 只能后置比较运算符
== !=> < >= <=逻辑运算符
&& || !位运算符
& | ^ &^ // 与、或、异或、与非<< >> // 左移、右移赋值运算符
= += -= *= /= %=&= |= ^= <<= >>= &^=取址与解引用
&x // 取地址*p // 解引用字符串
字符串基础
s := "hello"s := `multilinestring` // 原始字符串 // 字符串不可变// s[0] = 'H' // 错误 len(s) // 字节长度字符串操作
import "strings"strings.Contains(s, "sub")strings.HasPrefix(s, "pre")strings.HasSuffix(s, "suf")strings.Index(s, "sub")strings.LastIndex(s, "sub")strings.Count(s, "sub")strings.ToUpper(s)strings.ToLower(s)strings.Title(s)strings.TrimSpace(s)strings.Trim(s, "cutset")strings.TrimLeft(s, "cutset")strings.TrimRight(s, "cutset")字符串分割与拼接
parts := strings.Split(s, " ")joined := strings.Join(parts, "-")repeated := strings.Repeat("ab", 3)strings.Replace(s, "old", "new", n)strings.ReplaceAll(s, "old", "new")字符串构建
import "strings"var sb strings.Buildersb.WriteString("Hello")sb.WriteString(" World")result := sb.String()// 格式化s := fmt.Sprintf("Name: %s, Age: %d", name, age)集合数据结构
数组
var arr [5]intarr := [5]int{1, 2, 3, 4, 5}arr := [...]int{1, 2, 3} // 自动推导长度len(arr) // 长度// 遍历for i, v := range arr { fmt.Println(i, v)}切片
// 创建切片s := []int{1, 2, 3}s := make([]int, 5) // 长度 5s := make([]int, 0, 10) // 长度 0,容量 10// 操作s = append(s, 4)s = append(s, 5, 6, 7)s = append(s, other...)len(s) // 长度cap(s) // 容量// 切片操作sub := s[1:3] // [1, 3)sub := s[:3] // 前 3 个sub := s[2:] // 从索引 2 到末尾映射 (Map)
// 创建m := make(map[string]int)m := map[string]int{ "alice": 25, "bob": 30,}// 操作m["key"] = 100value := m["key"]// 检查键是否存在value, ok := m["key"]if ok { fmt.Println(value)}delete(m, "key")len(m)// 遍历for key, value := range m { fmt.Println(key, value)}控制流
if / else
if condition { // 执行} else if other { // 执行} else { // 执行}// if 带初始化语句if err := doSomething(); err != nil { return err}switch
switch value { case 1: fmt.Println("one") case 2, 3: fmt.Println("two or three") default: fmt.Println("other")}// 无条件 switchswitch { case x < 0: fmt.Println("negative") case x == 0: fmt.Println("zero") default: fmt.Println("positive")}for 循环
// C 风格 forfor i := 0; i < 10; i++ { fmt.Println(i)}// while 风格for condition { // 执行}// 无限循环for { // 执行 if done { break }}// range 遍历for i, v := range slice { fmt.Println(i, v)}// 只要值for _, v := range slice { fmt.Println(v)}跳转语句
break // 退出循环continue // 跳过本次return // 返回// 标签跳转outer:for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if i == 1 && j == 1 { break outer } }}defer
func example() { defer fmt.Println("World") // 函数返回前执行 fmt.Println("Hello") // 输出:Hello World}// 常用于资源清理file, err := os.Open("file.txt")defer file.Close()函数
函数定义
func add(a, b int) int { return a + b}// 多返回值func swap(a, b string) (string, string) { return b, a}// 命名返回值func divide(a, b int) (result int, err error) { if b == 0 { err = errors.New("division by zero") return } result = a / b return}可变参数
func sum(nums ...int) int { total := 0 for _, n := range nums { total += n } return total}result := sum(1, 2, 3, 4, 5)匿名函数与闭包
// 匿名函数fn := func(x int) int { return x * 2}// 立即执行result := func(x int) int { return x * 2}(5)// 闭包func counter() func() int { count := 0 return func() int { count++ return count }}高阶函数
func apply(fn func(int) int, value int) int { return fn(value)}func multiplier(factor int) func(int) int { return func(x int) int { return x * factor }}结构体与方法
结构体定义
type Person struct { Name string Age int}// 创建实例p1 := Person{Name: "Alice", Age: 25}p2 := Person{"Bob", 30}p3 := &Person{Name: "Charlie"}方法
func (p Person) Greet() string { return "Hello, I'm " + p.Name}// 指针接收者(可修改)func (p *Person) HaveBirthday() { p.Age++}p := Person{Name: "Alice", Age: 25}p.HaveBirthday()嵌入(组合)
type Address struct { City string Country string}type Employee struct { Person // 嵌入 Address // 嵌入 Salary int}e := Employee{ Person: Person{Name: "Alice", Age: 25}, Salary: 5000,}fmt.Println(e.Name) // 直接访问嵌入字段接口
接口定义
type Reader interface { Read(p []byte) (n int, err error)}type Writer interface { Write(p []byte) (n int, err error)}// 组合接口type ReadWriter interface { Reader Writer}实现接口
type MyReader struct{}func (r MyReader) Read(p []byte) (n int, err error) { // 实现细节 return len(p), nil}// 隐式实现,无需声明var r Reader = MyReader{}空接口
// interface{} 或 any (Go 1.18+) 可以表示任何类型var i interface{} = "hello"var a any = 42类型断言
var i interface{} = "hello"// 类型断言s := i.(string)// 安全断言s, ok := i.(string)if ok { fmt.Println(s)}// 类型判断switch v := i.(type) {case int: fmt.Printf("int: %d\n", v)case string: fmt.Printf("string: %s\n", v)default: fmt.Printf("unknown\n")}错误处理
错误处理模式
result, err := someFunction()if err != nil { return err // 或 log.Fatal(err)}// 使用 errors 包import "errors"err := errors.New("something went wrong")err := fmt.Errorf("error: %s", msg)自定义错误
type MyError struct { Code int Message string}func (e *MyError) Error() string { return fmt.Sprintf("error %d: %s", e.Code, e.Message)}err := &MyError{Code: 404, Message: "Not Found"}错误包装
Go 1.13+
import "errors"err := fmt.Errorf("failed to process: %w", originalErr)// 检查错误if errors.Is(err, os.ErrNotExist) { // 处理}// 类型判断var pathErr *os.PathErrorif errors.As(err, &pathErr) { fmt.Println(pathErr.Path)}panic 与 recover
// panic 导致程序崩溃panic("something went wrong")// recover 捕获 panicfunc safeDivide(a, b int) (result int) { defer func() { if r := recover(); r != nil { fmt.Println("Recovered:", r) result = 0 } }() result = a / b return}并发编程
Goroutine
// 启动 goroutinego func() { fmt.Println("Running in goroutine")}()go processData(data)// 匿名 goroutinego func(msg string) { fmt.Println(msg)}("Hello")Channel
// 创建 channelch := make(chan int)ch := make(chan int, 10) // 带缓冲// 发送ch <- 42// 接收value := <-ch// 关闭close(ch)// 检查 channel 是否关闭value, ok := <-chif !ok { fmt.Println("Channel closed")}Select
select {case msg := <-ch1: fmt.Println("Received from ch1:", msg)case msg := <-ch2: fmt.Println("Received from ch2:", msg)case <-time.After(time.Second): fmt.Println("Timeout")default: fmt.Println("No communication")}WaitGroup
import "sync"var wg sync.WaitGroupfor i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() fmt.Println("Worker", id) }(i)}wg.Wait()Mutex
import "sync"var mu sync.Mutexvar counter intmu.Lock()counter++mu.Unlock()// RWMutexvar rwMu sync.RWMutexrwMu.RLock() // 读锁rwMu.RUnlock()rwMu.Lock() // 写锁rwMu.Unlock()文件操作
读取文件
import "os"// 读取全部data, err := os.ReadFile("file.txt")if err != nil { log.Fatal(err)}fmt.Println(string(data))// 逐行读取file, err := os.Open("file.txt")defer file.Close()scanner := bufio.NewScanner(file)for scanner.Scan() { fmt.Println(scanner.Text())}写入文件
// 写入全部err := os.WriteFile("file.txt", []byte("content"), 0644)// 追加写入file, err := os.OpenFile("file.txt", os.O_APPEND|os.O_WRONLY, 0644)defer file.Close()file.WriteString("more content\n")JSON 操作
import "encoding/json"// 序列化data, err := json.Marshal(obj)jsonStr, err := json.MarshalIndent(obj, "", " ")// 反序列化var obj MyStructerr := json.Unmarshal(data, &obj)泛型
泛型函数
Go 1.18+
func Min[T constraints.Ordered](a, b T) T { if a < b { return a } return b}result := Min(1, 2)result := Min("a", "b")泛型类型
type Stack[T any] struct { items []T}func (s *Stack[T]) Push(item T) { s.items = append(s.items, item)}func (s *Stack[T]) Pop() T { item := s.items[len(s.items)-1] s.items = s.items[:len(s.items)-1] return item}最佳实践
代码风格
// 使用 gofmt 格式化代码// 使用短变量声明x := 10// 尽早返回if err != nil { return err}// 使用有意义的名称count := len(users) // 好c := len(users) // 不好错误处理
// 不要忽略错误result, err := someFunc()if err != nil { return fmt.Errorf("failed to do something: %w", err)}// 使用 defer 清理资源file, err := os.Open("file.txt")if err != nil { return err}defer file.Close()并发安全
// 不要通过共享内存通信,而要通过通信共享内存// 使用 channel 传递数据ch := make(chan int)go func() { ch <- processData()}()result := <-ch// 必要时使用 mutexvar mu sync.Mutexmu.Lock()// 访问共享资源mu.Unlock()工具链
Go 命令
go run main.go # 运行go build # 编译go test # 测试go mod init # 初始化模块go mod tidy # 整理依赖go get package # 获取包go install # 安装go fmt # 格式化go vet # 静态分析测试
// example_test.gopackage exampleimport "testing"func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("Expected 5, got %d", result) }}// 基准测试func BenchmarkAdd(b *testing.B) { for i := 0; i < b.N; i++ { Add(2, 3) }}常用工具
# golangci-lint - 代码检查golangci-lint run# go-staticcheck - 静态分析staticcheck ./...# godoc - 文档生成godoc -http=:6060