1. 包(package)与导入(import)
每个源文件以 package 名称 开头;可执行程序入口包名为 main。
标准形式
package main
import (
"fmt"
"strings"
)
点导入、别名、空白导入
. 将包符号导入当前命名空间(少用)。_ 仅执行包的 init,用于副作用(如驱动注册)。
import . "fmt" // 可直接 Println
import bar "path/to/foo" // 用 bar 访问
import _ "image/png" // 注册 PNG 解码器
2. 标识符、关键字与可见性
命名规则
字母、数字、下划线;不能以数字开头。25 个关键字不可作标识符:break case chan const continue default defer else fallthrough for func go goto if import interface map package range return select struct switch type var。
导出(可见性)
首字母大写的标识符对包外可见;小写为包内私有。
type User struct { Name string; age int } // Name 导出,age 不导出
空白标识符 _
丢弃不需要的返回值或导入副作用。
_, err := os.Open("a.txt")
for _, v := range slice { _ = v }
3. 常量(const)与 iota
常量声明
常量必须是编译期可确定值;可成组声明。
const Pi = 3.14
const (
StatusOK = 200
StatusNotFound = 404
)
iota 计数器
在 const ( ) 块中从 0 递增,每行 +1;可配合表达式。
const (
_ = iota // 0,丢弃
KB = 1 << (10 * iota) // 1 << 10
MB
GB
)
4. 变量(var)与短变量声明(:=)
var 多种形式
var x int
var y, z = 1, "hi"
var a, b int = 1, 2
var p = &x
短声明 :=
仅在函数内使用;左侧至少有一个新变量名时,可对已有变量重新赋值混合声明。
func f() {
i := 0
j, k := 1, 2
i, m := 3, 4 // i 重赋值,m 新声明
_ = j; _ = k; _ = m
}
5. 预定义类型与复合类型字面量
布尔与数值
bool。int int8 int16 int32 int64;uint uint8(即 byte) uint16 uint32 uint64 uintptr。float32 float64。complex64 complex128。
rune 与 string
rune 是 int32 别名,表示 Unicode 码点。
复合类型关键字
array slice struct map chan func interface 等由类型构造符组成。
6. 零值、类型转换与比较
零值
未显式初始化时:数值 0、bool false、指针/nil 接口/slice/map/channel 为 nil,string 为 ""。
显式类型转换
Go 无隐式数值转换(除常量与部分无类型常量上下文)。
var u uint = uint(i)
f := float64(3)
可比较类型
== != 适用于布尔、数值、字符串、指针、channel、接口(动态类型可比)、struct(字段均可比)、array(元素可比)。slice、map、函数类型不可比较(可与 nil 比)。
7. 运算符
算术与位运算
+ - * / %;整数 & | ^ &^ << >>;一元 + - ! ^ * & <-(接收)。
逻辑与比较
&& || !。== != < <= > >=。
寻址与解引用
x := 1
p := &x
*p = 2
8. 字符串与字符
字面量与 raw string
s := "行\n换行"
raw := `C:\path\file` // 反引号内不转义
不可变与字节/rune
string 只读字节序列;修改需转为 []byte 或 []rune。
b := []byte(s)
r := []rune(s)
9. 数组(array)
长度是类型的一部分:[4]int 与 [5]int 不同类型。
var a [3]int
a[0] = 1
b := [...]int{1, 2, 3} // 长度由初始化推导
10. 切片(slice)
声明与字面量
var s []int
s = []int{1, 2, 3}
s = make([]int, 3, 8) // len=3 cap=8
切片表达式与共享底层数组
low, high, max := 1, 3, 5
sub := base[low:high] // 容量到 base 末尾
sub2 := base[low:high:max] // 三索引,容量 max-low
append 与 copy
s = append(s, 4, 5)
n := copy(dst, src)
11. 映射(map)
var m map[string]int // nil,不能写入
m = make(map[string]int)
m["a"] = 1
delete(m, "a")
v, ok := m["a"] // 逗号 ok 判断键是否存在
12. 指针(pointer)
Go 无指针运算(除 unsafe);不能得到任意临时值的地址(部分例外如复合字面量取址规则)。
type T struct{ X int }
p := &T{X: 1}
p.X = 2 // 隐式解引用
13. 结构体(struct)、匿名字段与标签
定义与字面量
type Point struct {
X, Y float64
}
p := Point{X: 1, Y: 2}
q := Point{3, 4} // 按字段顺序,需完整或全用键名
嵌入(embedding)
匿名字段提升字段与方法,类似“组合”。
type Inner struct { A int }
type Outer struct {
Inner // 嵌入
B int
}
var o Outer
o.A = 1 // 提升自 Inner
结构体标签(tag)
type User struct {
Name string `json:"name" xml:"Name"`
}
14. 方法(method)
值接收者与指针接收者
指针接收者可修改接收者、避免大结构体拷贝;值接收者操作副本。
func (p Point) Dist() float64 { return p.X * p.X }
func (p *Point) Move(dx, dy float64) {
p.X += dx; p.Y += dy
}
15. 接口(interface)
接口类型与实现
实现是隐式的:类型方法集包含接口所需全部方法即满足接口。
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
}
空接口与类型断言
var any interface{} = 42
// Go 1.18+ 可用 any 代替 interface{}
v := any.(int) // 失败则 panic
w, ok := any.(int) // ok 为 false 安全
类型开关 type switch
switch t := any.(type) {
case int:
_ = t
case string:
_ = t
default:
}
16. 函数(func)
声明、多返回值、命名返回值
func Div(a, b int) (q int, r int, err error) {
if b == 0 {
err = fmt.Errorf("zero divisor")
return // 裸 return,返回命名零值
}
q, r = a/b, a%b
return
}
可变参数
func Sum(nums ...int) int {
s := 0
for _, n := range nums { s += n }
return s
}
函数类型与匿名函数
type Handler func(int) int
var fn Handler = func(x int) int { return x + 1 }
17. defer
defer 语句推迟到外层函数返回前执行;参数在 defer 语句处立即求值。多个 defer 后进先出(栈)。
func read() error {
f, err := os.Open("f.txt")
if err != nil { return err }
defer f.Close()
// ...
return nil
}
18. 控制流:if、for、switch、select、goto
if 可带短声明
if err := run(); err != nil {
return err
} else {
// else 块内 err 仍可见
}
for:唯一循环关键字
for i := 0; i < 10; i++ { }
for cond { } // 等同 while
for { } // 死循环
for k, v := range m { }
switch 与 fallthrough
switch x := v.(type) { // v 须为接口类型值
case int:
fallthrough // 继续执行下一 case 体(不重新判断)
case int64:
default:
_ = x
}
select:多路 channel
select {
case v := <-ch1:
_ = v
case ch2 <- x:
default:
}
break / continue 与标签
Outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
break Outer
}
}
goto(受限跳转)
不能跳入块内越过变量声明等;实际少用。
19. range 详解
// slice/array: 索引, 值副本
for i, v := range s { _ = i; _ = v }
// map: 键, 值
for k, v := range m { _ = k; _ = v }
// string: 索引(byte 偏移), rune(码点值)
for i, r := range "你好" { _ = i; _ = r }
// channel: 接收直到关闭
for v := range ch { _ = v }
20. make 与 new
new(T)
分配内存,置零值,返回 *T。用于值类型指针。
p := new(int)
*p = 7
make
仅用于 slice、map、chan,返回已初始化(非 nil)的引用类型值。
s := make([]int, 0, 10)
m := make(map[string]int)
c := make(chan int, 2)
21. 泛型(Go 1.18+)
类型参数与约束
// import "constraints"
func Min[T constraints.Ordered](a, b T) T {
if a < b { return a }
return b
}
type Vector[T any] struct { data []T }
接口约束、并集、~ 底层类型
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type MyInt int
func F[T Signed](x T) {} // MyInt 底层为 int 可满足 ~int
comparable 预声明约束
func Keys[K comparable, V any](m map[K]V) []K {
out := make([]K, 0, len(m))
for k := range m { out = append(out, k) }
return out
}
22. 类型定义(type)与类型别名
定义新命名类型
type ID uint64
type ErrFunc func() error
类型别名(与原名完全同一类型)
// 与右侧为同一类型,可互换赋值
type IntList = []int
type Handler = func() error
23. 复合字面量、取址与可变参数展开
结构体、数组、切片、map、channel 字面量
p := &Point{X: 1, Y: 2} // T{...} 取址,堆或栈由编译器决定
m := map[string]int{"a": 1}
s := []int{1, 2, 3}
a := [...]int{1, 2} // 数组长度由初始化推导
调用时将切片展开为多个参数
func Sum(nums ...int) int { /* ... */ return 0 }
vals := []int{1, 2, 3}
Sum(vals...) // 等价 Sum(1,2,3),切片须与 ...T 元素类型一致
24. 并发:goroutine、channel、sync 要点
go 语句
go func() { fmt.Println("async") }()
channel:创建、方向、缓冲
ch := make(chan int) // 无缓冲,同步握手
buf := make(chan int, 10) // 缓冲
var sendOnly chan<- int = ch
var recvOnly <-chan int = ch
关闭与 range
close(ch)
for v := range ch { _ = v }
同步原语(语法级常用配合)
sync.Mutex RWMutex WaitGroup Once sync/atomic 等用于共享内存同步;与 channel 可按场景选择。
25. 错误(error)处理惯用法
error 接口
type error interface {
Error() string
}
构造与包装(Go 1.13+)
err := errors.New("plain")
err = fmt.Errorf("wrap: %w", err)
if errors.Is(err, os.ErrNotExist) { }
var pathErr *fs.PathError
if errors.As(err, &pathErr) { }
26. panic 与 recover
panic 停止当前 goroutine 正常执行,展开 defer;recover() 仅在 defer 内调用可捕获 panic 值。常规错误用 error 返回,不用 panic 控制流。
defer func() {
if r := recover(); r != nil {
fmt.Println("recovered:", r)
}
}()
panic("oops")
27. init 函数
每个包可有多个 func init(),在 main 之前、按依赖顺序自动调用;不可被引用,无参数无返回值。
func init() {
// 包级初始化
}