Go语言从基础到进阶语法详解

Go语言从基础到进阶语法详解

目录

基础语法

1. 语言基础

包与入口

Go程序由包(package)组成,每个文件必须属于一个包。可执行程序的入口是main包中的main函数:

package main

import "fmt"

func main() {
    fmt.Println("Hello, Go 1.24!")
}

变量声明

Go提供多种变量声明方式:

// 标准声明
var a int = 10
var b string = "hello"

// 类型推断
var c = 3.14 // float64
var d = true // bool

// 短声明(仅函数内可用)
e := "short declaration"

内置函数(Go 1.21+新增)

Go 1.21引入minmaxclear三个实用内置函数:

package main

import "fmt"

func main() {
    // min/max支持多种数字类型和字符串
    fmt.Println(min(123))        // 1
    fmt.Println(max(1.52.50.5))  // 2.5
    fmt.Println(min("a""b""c"))  // "a"(字典序)
    
    // clear清空map或归零切片
    m := map[string]int{"a"1"b"2}
    clear(m)
    fmt.Println(m) // map[]
    
    s := []int{123}
    clear(s)
    fmt.Println(s) // [0 0 0](长度不变)
}

2. 控制流

条件语句

Go的if语句支持初始化表达式:

if err := doSomething(); err != nil {
    fmt.Println("错误:", err)
else {
    fmt.Println("成功")
}

循环语句

Go只有for一种循环结构,但支持多种形式:

// 基本for循环
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// for-range遍历
nums := []int{123}
for idx, val := range nums {
    fmt.Printf("索引: %d, 值: %d\n", idx, val)
}

// Go 1.22+整数范围遍历
for i := range 5 { // 等价于0-4
    fmt.Println(i)
}

循环变量作用域(Go 1.22+)

Go 1.22修复了循环变量闭包捕获问题:

// Go 1.22前(有问题)
for i := 0; i < 3; i++ {
    defer func() { fmt.Println(i) }() // 输出3次3
}

// Go 1.22+(修复后)
for i := 0; i < 3; i++ {
    defer func() { fmt.Println(i) }() // 输出0, 1, 2
}

3. 函数与方法

函数定义

Go函数支持多返回值:

// 返回两个值
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("除数不能为0")
    }
    return a / b, nil
}

// 命名返回值
func calculate() (sum, product int) {
    sum = 1 + 2
    product = 1 * 2
    return // 无需显式指定返回变量
}

方法

方法是带接收者的函数:

type Circle struct {
    Radius float64
}

// 值接收者
func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

// 指针接收者(修改接收者)
func (c *Circle) Scale(factor float64) {
    c.Radius *= factor
}

4. 复合数据类型

切片(Slice)

切片是动态数组,支持自动扩容:

// 创建切片
s1 := []int{123}
s2 := make([]int5// 长度5,容量5
s3 := make([]int310// 长度3,容量10

// 切片操作
s := []int{01234}
sub := s[1:3// [1, 2](左闭右开)

Go 1.21新增slices包提供泛型操作:

import "slices"

nums := []int{312}
slices.Sort(nums) // [1, 2, 3]
idx := slices.Index(nums, 2// 1(查找元素位置)

映射(Map)

Map是键值对集合:

// 创建map
m1 := map[string]int{"a"1"b"2}
m2 := make(map[string]int)

// 安全访问
val, ok := m1["c"]
if ok {
    fmt.Println("c的值:", val)
else {
    fmt.Println("c不存在")
}

Go 1.21新增maps包:

import "maps"

m := map[string]int{"a"1"b"2"c"3}
// 删除值小于2的键
maps.DeleteFunc(m, func(k string, v int) bool {
    return v < 2
})
fmt.Println(m) // map[b:2 c:3]

进阶语法

1. 泛型编程

基础泛型函数

Go 1.18引入泛型,支持类型参数:

// 泛型函数:返回两个值中较小的一个
func Min[T constraints.Ordered](a, b T) T {
    if a < b {
        return a
    }
    return b
}

func main() {
    fmt.Println(Min(12))     // 1
    fmt.Println(Min(1.50.5)) // 0.5
}

泛型类型

定义泛型结构体:

// 泛型链表
type List[T any] struct {
    Head *Node[T]
}

type Node[T any] struct {
    Val  T
    Next *Node[T]
}

// 泛型方法
func (l *List[T]) Append(val T) {
    // ...实现逻辑...
}

泛型类型别名(Go 1.24+)

Go 1.24支持泛型类型别名:

// 定义泛型类型
type Tree[T any] struct {
    Val   T
    Left  *Tree[T]
    Right *Tree[T]
}

// 泛型类型别名
type IntTree = Tree[int]
type StringTree = Tree[string]

func main() {
    var it IntTree = Tree[int]{Val: 10}
    var st StringTree = Tree[string]{Val: "hello"}
}

2. 并发编程

Goroutine

轻量级线程,由Go运行时管理:

func sayHello() {
    fmt.Println("Hello, goroutine!")
}

func main() {
    go sayHello() // 启动goroutine
    time.Sleep(100 * time.Millisecond) // 等待goroutine执行
}

通道(Channel)

用于goroutine间通信:

// 创建通道
ch := make(chan int// 无缓冲通道
ch := make(chan int5// 缓冲通道,容量5

// 发送数据
go func() {
    ch <- 42 // 发送数据到通道
}()

// 接收数据
val := <-ch // 从通道接收数据
fmt.Println(val) // 42

Context包

管理goroutine生命周期:

func longRunningTask(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("任务取消:", ctx.Err())
            return
        default:
            fmt.Println("任务运行中...")
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    // 创建带5秒超时的上下文
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel() // 确保资源释放
    
    go longRunningTask(ctx)
    time.Sleep(10 * time.Second) // 等待超时
}

Context最佳实践

  • 使用context.Background()作为根上下文
  • 使用context.TODO()标记需要后续完善的上下文
  • 不要将context存储在结构体中,应作为函数参数传递

3. 错误处理

自定义错误

// 基本自定义错误
var ErrNotFound = errors.New("资源未找到")

// 带动态信息的错误
func NewValidationError(field string) error {
    return fmt.Errorf("字段验证失败: %s", field)
}

// Go 1.13+错误包装
err := fmt.Errorf("读取文件失败: %w", os.ErrNotExist)

错误处理策略

// 错误判断
if errors.Is(err, os.ErrNotExist) {
    // 处理文件不存在错误
}

// 错误类型断言
var validationErr *ValidationError
if errors.As(err, &validationErr) {
    // 处理验证错误
}

4. 高级特性

反射(Reflect)

在运行时检查类型信息:

import "reflect"

func inspect(v interface{}) {
    t := reflect.TypeOf(v)
    vv := reflect.ValueOf(v)
    
    fmt.Println("类型:", t)
    fmt.Println("值:", vv)
    
    // 调用方法(如果有)
    if m := vv.MethodByName("String"); m.IsValid() {
        // ...调用方法...
    }
}

注意:反射会使代码复杂且影响性能,谨慎使用。

模块化开发

使用Go Modules管理依赖:

# 初始化模块
go mod init example.com/myapp

# 添加依赖
go get github.com/some/dependency@v1.2.3

# 整理依赖
go mod tidy

附录:Go版本特性对比

版本 重要语法特性
1.18 泛型、模糊测试
1.19 泛型方法作用域修复
1.20 错误包装增强、unsafe包新增函数
1.21 min/max/clear内置函数、slices/maps包
1.22 循环变量作用域调整、整数范围for循环
1.24 泛型类型别名、迭代器增强
阅读: 6 | 发布时间: 2025-08-06 13:15:25