Skip to content

Go 语言基础

简介

Go(Golang)是 Google 开发的编译型静态语言,以简洁、高效、并发原生著称。

安装与配置

sh
# 下载安装 https://go.dev/dl/
# 验证
go version

# 环境变量
go env GOPATH   # 模块缓存路径
go env GOROOT   # Go 安装路径

推荐使用 Go Modules(1.16+ 默认开启):

sh
go mod init project-name  # 初始化模块
go mod tidy               # 整理依赖
go mod download           # 下载依赖

基础语法

Hello World

go
package main

import "fmt"

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

变量与常量

go
// 变量声明
var name string = "Go"
var version = 1.21               // 类型推断
count := 42                      // 短声明(函数内)

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

// 常量
const Pi = 3.14159
const (
    StatusOK = 200
    StatusNotFound = 404
)

基本类型

go
bool       // true / false

int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
uintptr

float32, float64
complex64, complex128

byte       // uint8 别名
rune       // int32 别名,表示 Unicode 码点

string     // 字符串,不可变

字符串

go
s := "Hello"
s[0]        // 'H' (byte)
len(s)      // 5
s + " Go"   // "Hello Go"
strings.HasPrefix(s, "He")  // true
strings.Split("a,b,c", ",") // ["a" "b" "c"]
strings.Join([]string{"a","b"}, "-") // "a-b"
strconv.Itoa(42)            // "42"
strconv.Atoi("42")          // 42, nil

条件判断

go
if score >= 90 {
    fmt.Println("A")
} else if score >= 60 {
    fmt.Println("B")
} else {
    fmt.Println("C")
}

// if 中声明临时变量
if err := doSomething(); err != nil {
    fmt.Println(err)
}

循环(仅 for)

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

// 类似 while
sum := 1
for sum < 100 {
    sum += sum
}

// 无限循环
for {
    break
}

// range 遍历
nums := []int{1, 2, 3}
for i, v := range nums {
    fmt.Println(i, v)
}

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

for i, c := range "hello" {
    fmt.Println(i, c)  // i 是字节下标,c 是 rune
}

Switch

go
switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("macOS")
case "linux":
    fmt.Println("Linux")
default:
    fmt.Println(os)
}

// 无表达式 switch(替代 if-else 链)
score := 85
switch {
case score >= 90:
    fmt.Println("A")
case score >= 60:
    fmt.Println("B")
default:
    fmt.Println("C")
}

函数

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

// 参数类型简写
func add(a, b int) int

// 多返回值
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("除零")
    }
    return a / b, nil
}

// 具名返回值
func split(sum int) (x, y int) {
    x = sum / 2
    y = sum - x
    return  // 裸返回(不推荐长函数中使用)
}

// 可变参数
func sum(nums ...int) int {
    total := 0
    for _, n := range nums {
        total += n
    }
    return total
}

// 函数作为参数
func apply(f func(int) int, n int) int {
    return f(n)
}

// 闭包
func counter() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}

defer

go
func readFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close()  // 函数返回前执行(后进先出)
    // 处理文件...
    return nil
}

// defer 栈
func example() {
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
    // 输出: 3 2 1
}

数组与切片

数组(固定长度)

go
var arr [3]int = [3]int{1, 2, 3}
arr2 := [...]int{4, 5, 6}  // 自动推断长度
len(arr)  // 3

切片(动态长度)

go
// 创建
s1 := []int{1, 2, 3}
s2 := make([]int, 5)        // len=5, cap=5
s3 := make([]int, 3, 5)     // len=3, cap=5

// 追加
s1 = append(s1, 4, 5)

// 切片操作
arr := [...]int{0, 1, 2, 3, 4, 5}
s := arr[1:4]               // [1 2 3]
s = arr[:3]                 // [0 1 2]
s = arr[3:]                 // [3 4 5]
s = arr[:]                  // [0 1 2 3 4 5]

// 复制
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)

// 遍历
for i, v := range s {
    fmt.Println(i, v)
}

Map

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

// 读写
m["key"] = 42
value := m["key"]
value, ok := m["key"]  // ok 表示键是否存在

// 删除
delete(m, "key")

// 遍历
for k, v := range m {
    fmt.Println(k, v)
}

结构体与方法

go
type User struct {
    ID   int
    Name string
    Age  int
}

// 创建实例
u1 := User{ID: 1, Name: "Alice", Age: 30}
u2 := User{ID: 2}              // 其余字段零值
u3 := new(User)                // 指针

// 方法(值接收者)
func (u User) Greet() string {
    return "Hello, " + u.Name
}

// 方法(指针接收者,可修改)
func (u *User) SetName(name string) {
    u.Name = name
}

// 使用
u := User{Name: "Bob"}
fmt.Println(u.Greet())  // Hello, Bob
u.SetName("Alice")

接口

go
type Animal interface {
    Speak() string
}

type Dog struct{}
func (d Dog) Speak() string { return "汪汪" }

type Cat struct{}
func (c Cat) Speak() string { return "喵喵" }

// 使用
func PrintSound(a Animal) {
    fmt.Println(a.Speak())
}

// 空接口(Go 1.18+ 推荐用 any)
var v any = 42
v = "hello"
v = 3.14

类型断言

go
var i any = "hello"
s, ok := i.(string)     // ok=true, s="hello"
n, ok := i.(int)        // ok=false

switch v := i.(type) {
case string:
    fmt.Println("string:", v)
case int:
    fmt.Println("int:", v)
default:
    fmt.Println("unknown")
}

错误处理

go
// 自定义错误
type MyError struct {
    Code    int
    Message string
}

func (e *MyError) Error() string {
    return fmt.Sprintf("error %d: %s", e.Code, e.Message)
}

// 使用
func doSomething() error {
    return &MyError{Code: 400, Message: "bad request"}
}

// 错误判断
err := doSomething()
if err != nil {
    var myErr *MyError
    if errors.As(err, &myErr) {
        fmt.Println(myErr.Code)
    }
}

// 快速创建错误
errors.New("something went wrong")
fmt.Errorf("user %d not found", id)

并发

Goroutine

go
go func() {
    fmt.Println("并行执行")
}()

go doSomething()  // 只要是函数就可以

Channel

go
// 创建
ch := make(chan int)
ch := make(chan int, 10)   // 缓冲通道

// 发送与接收
ch <- 42
value := <-ch

// 关闭
close(ch)
value, ok := <-ch  // ok=false 表示通道已关闭

// range 遍历通道
for v := range ch {
    fmt.Println(v)
}

// select(多路复用)
select {
case v := <-ch1:
    fmt.Println(v)
case ch2 <- 42:
    fmt.Println("发送成功")
case <-time.After(1 * time.Second):
    fmt.Println("超时")
default:
    fmt.Println("无就绪通道")
}

示例:并发 worker

go
func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        time.Sleep(time.Second)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 10)
    results := make(chan int, 10)

    // 启动 3 个 worker
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    // 发送任务
    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    // 收集结果
    for r := 1; r <= 5; r++ {
        <-results
    }
}

sync 包

go
var mu sync.Mutex
mu.Lock()
// 临界区
mu.Unlock()

// WaitGroup
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(id int) {
        defer wg.Done()
        fmt.Println(id)
    }(i)
}
wg.Wait()  // 等待所有 goroutine 完成

包管理

go
// 文件结构
myproject/
├── go.mod          # 模块定义(module name, go 版本, 依赖)
├── main.go
└── utils/
    └── helper.go
go
// main.go
package main

import "myproject/utils"

func main() {
    utils.Hello()
}
go
// utils/helper.go
package utils

import "fmt"

func Hello() {
    fmt.Println("Hello from utils")
}

go.mod 示例

module github.com/user/myproject

go 1.22

require (
    github.com/gin-gonic/gin v1.9.1
)

常用命令

sh
go build                    # 编译
go build -o app main.go     # 输出文件名
go run main.go              # 编译并运行
go test ./...               # 运行所有测试
go test -v ./...            # 详细输出
go test -bench=.            # 性能测试
go fmt ./...                # 格式化代码
go vet ./...                # 静态检查
go mod tidy                 # 整理依赖
go mod graph                # 查看依赖图
go env                      # 查看环境变量
go doc fmt.Println          # 查看文档

常用标准库

用途
fmt格式化 I/O
net/httpHTTP 客户端/服务端
encoding/jsonJSON 编解码
io / os文件与流操作
strings / strconv字符串处理
time时间操作
sync并发原语
context上下文控制(超时、取消)
errors错误处理
database/sql数据库接口
flag命令行参数解析
testing测试框架

常用开发库

go
import (
    "github.com/gin-gonic/gin"       // Web 框架
    "github.com/gorilla/mux"         // HTTP 路由
    "github.com/go-sql-driver/mysql" // MySQL 驱动
    "github.com/lib/pq"              // PostgreSQL 驱动
    "github.com/redis/go-redis/v9"   // Redis 客户端
    "github.com/fsnotify/fsnotify"   // 文件监控
    "github.com/spf13/cobra"         // CLI 框架
    "github.com/spf13/viper"         // 配置管理
    "github.com/jmoiron/sqlx"        // 数据库扩展
    "github.com/golang-jwt/jwt/v5"   // JWT
    "github.com/stretchr/testify"    // 测试断言
    "go.uber.org/zap"                // 日志
)

蜀ICP备2025150039号