Skip to content

Go 语法基础

Go 语法精炼,关键字仅 25 个。本文覆盖变量声明、数据类型、流程控制与函数四大基础主题。

变量声明

go
// 显式声明
var name string = "Go"
var age int

// 类型推断
var name = "Go"

// 短变量声明(仅函数内部使用)
name := "Go"
age := 15

// 多变量声明
var x, y, z int = 1, 2, 3
a, b := "hello", true

// 声明但不初始化(零值)
var count int        // 0
var s string         // ""
var b bool           // false
var p *int           // nil

Go 中未显式初始化的变量会被赋予零值(zero value),这是与 C/Java 不同的重要特性。

数据类型

基本类型

go
bool          // true / false
string        // UTF-8 字符串
int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
uintptr       // 指针类型
byte          // uint8 别名
rune          // int32 别名,表示 Unicode 码点
float32, float64
complex64, complex128

通常直接用 int / uint / float64,除非有特定内存或互操作需求。

复合类型

go
// 数组:固定长度
var arr [3]int = [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3}   // 由编译器推断长度

// 切片:动态数组(最常用)
nums := []int{1, 2, 3}
nums = append(nums, 4)
slice := nums[1:3]          // 左闭右开 [1,3)

// map:键值对
m := map[string]int{"a": 1, "b": 2}
m["c"] = 3
delete(m, "a")
v, ok := m["b"]              // ok 表示键是否存在

// struct:结构体
type Point struct {
    X, Y int
}

// interface:接口
type Stringer interface {
    String() string
}

// chan:通道(见并发编程)
ch := make(chan int)

切片底层结构

切片是对底层数组的视图,包含指针、长度(len)和容量(cap):

go
s := make([]int, 2, 5)   // len=2, cap=5
fmt.Println(len(s), cap(s))

// append 超过容量会分配新的底层数组
s = append(s, 1, 2, 3, 4)
fmt.Println(len(s), cap(s))   // 6, 可能 10

流程控制

Go 只有 for 一种循环,没有 whileif 支持短语句;switch 自动 break。

if / else

go
// 标准
if score >= 90 {
    grade = "A"
} else if score >= 60 {
    grade = "B"
} else {
    grade = "C"
}

// Go 特有的 if 短语句(作用域仅限于 if 块)
if err := doSomething(); err != nil {
    return err
}

for 循环

go
// 经典三段式
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// 条件循环(相当于 while)
for sum < 100 {
    sum += 1
}

// 无限循环
for {
    // 通常需要 break 退出
}

// for-range 遍历
nums := []int{1, 2, 3}
for index, value := range nums {
    fmt.Printf("index: %d, value: %d\n", index, value)
}

// 遍历 map
m := map[string]int{"a": 1}
for k, v := range m {
    fmt.Println(k, v)
}

// 只取 key
for k := range m {
    fmt.Println(k)
}

switch

go
// 自动 break,无需手动添加
switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("macOS")
case "linux":
    fmt.Println("Linux")
default:
    fmt.Println(os)
}

// 无表达式 switch(相当于 if-else 链)
switch {
case score >= 90:
    grade = "A"
case score >= 60:
    grade = "B"
default:
    grade = "C"
}

函数

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

// 参数类型简写
func add(a, b int) int {
    return a + b
}

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

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

// 可变参数
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}
sum(1, 2, 3)
sum([]int{1, 2, 3}...)   // 切片展开传入

// 函数是一等公民(可作为参数/返回值)
func compute(fn func(float64, float64) float64) float64 {
    return fn(3, 4)
}

延迟执行 defer

go
func readFile() error {
    f, err := os.Open("file.txt")
    if err != nil {
        return err
    }
    defer f.Close()   // 函数返回前执行,常用于释放资源

    // 多个 defer 遵循后进先出(LIFO)顺序
    defer fmt.Println("first")
    defer fmt.Println("second")   // 先打印
    return nil
}

作者:yanshaodong