主题
Go 语言介绍
Go(又称 Golang)是 Google 于 2009 年发布的开源编程语言,由 Robert Griesemer、Rob Pike 和 Ken Thompson 设计。Go 的设计目标是兼顾开发效率和运行性能,原生支持并发编程,拥有简洁的语法和快速的编译速度,特别适合构建高并发的网络服务和分布式系统。
语言特性
| 特性 | 说明 |
|---|---|
| 简洁性 | 语法精炼,关键字仅 25 个,学习曲线平缓 |
| 并发支持 | 原生 goroutine + channel,轻松实现高并发 |
| 静态类型 | 编译时类型检查,安全可靠 |
| 快速编译 | 编译速度极快,大型项目秒级编译 |
| 垃圾回收 | 自动内存管理,无需手动释放 |
| 跨平台 | 支持 Linux / macOS / Windows 等多平台交叉编译 |
| 标准库丰富 | 内置 HTTP、JSON、加密、测试等常用库 |
| 静态链接 | 编译为单一二进制文件,部署极其简单 |
基础语法
变量声明
go
// 显式声明
var name string = "Go"
var age int
// 短变量声明(函数内使用)
name := "Go"
age := 15
// 多变量声明
var x, y, z int = 1, 2, 3
a, b := "hello", true数据类型
go
// 基本类型
bool // true / false
string // UTF-8 字符串
int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
float32, float64
complex64, complex128
byte // uint8 别名
rune // int32 别名,表示 Unicode 码点
// 复合类型
array // 固定长度数组,如 [3]int{1, 2, 3}
slice // 动态数组,如 []int{1, 2, 3}
map // 键值对,如 map[string]int{"a": 1}
struct // 结构体
interface // 接口
chan // 通道流程控制
go
// if-else
if score >= 90 {
grade = "A"
} else if score >= 60 {
grade = "B"
} else {
grade = "C"
}
// Go 特有的 if 短语句
if err := doSomething(); err != nil {
return err
}
// for 循环(Go 只有 for 一种循环)
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// for-range 遍历
nums := []int{1, 2, 3}
for index, value := range nums {
fmt.Printf("index: %d, value: %d\n", index, value)
}
// switch(自动 break,无需手动添加)
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("macOS")
case "linux":
fmt.Println("Linux")
default:
fmt.Println(os)
}函数
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
}
// 命名返回值
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 裸 return,返回命名返回值
}
// 可变参数
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
// 函数是一等公民
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}结构体与方法
go
// 定义结构体
type Person struct {
Name string
Age int
}
// 值接收者方法(只读)
func (p Person) Greet() string {
return "Hello, I'm " + p.Name
}
// 指针接收者方法(可修改)
func (p *Person) Birthday() {
p.Age++
}
// 使用
func main() {
p := Person{Name: "张三", Age: 25}
p.Birthday()
fmt.Println(p.Greet()) // Hello, I'm 张三
fmt.Println(p.Age) // 26
}接口
Go 采用隐式实现,类型只需实现接口的所有方法即视为实现了该接口,无需显式声明。
go
// 定义接口
type Writer interface {
Write([]byte) (int, error)
}
type Closer interface {
Close() error
}
// 接口组合
type ReadWriteCloser interface {
Reader
Writer
Closer
}
// 隐式实现:任何实现了 Write 方法的类型都自动实现了 Writer 接口
type MyWriter struct{}
func (m MyWriter) Write(data []byte) (int, error) {
// 实现细节
return len(data), nil
}
// 空接口 interface{} / any 可以表示任意类型
func describe(v any) {
fmt.Printf("value: %v, type: %T\n", v, v)
}
// 类型断言
var w Writer = MyWriter{}
if mw, ok := w.(MyWriter); ok {
fmt.Println("断言成功:", mw)
}
// 类型 switch
switch v := w.(type) {
case MyWriter:
fmt.Println("MyWriter")
case *os.File:
fmt.Println("*os.File")
default:
fmt.Printf("unknown type: %T\n", v)
}并发编程
Go 的并发模型基于 goroutine 和 channel,是 CSP(Communicating Sequential Processes)的实践。
go
// goroutine:轻量级线程
func say(s string) {
for i := 0; i < 3; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world") // 启动一个 goroutine
say("hello") // 主 goroutine
}
// channel:goroutine 间的通信
func main() {
ch := make(chan int)
go func() {
ch <- 42 // 发送
}()
val := <-ch // 接收
fmt.Println(val)
}
// 带缓冲的 channel
ch := make(chan int, 100)
// select 多路复用
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
// sync 包同步原语
var wg sync.WaitGroup
var mu sync.Mutex
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
mu.Lock()
// 临界区代码
mu.Unlock()
}(i)
}
wg.Wait() // 等待所有 goroutine 完成错误处理
Go 不使用异常,而是通过返回 error 值来显式处理错误。
go
// 标准错误处理模式
f, err := os.Open("file.txt")
if err != nil {
return fmt.Errorf("打开文件失败: %w", err)
}
defer f.Close()
// 自定义错误
type MyError struct {
Code int
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("error %d: %s", e.Code, e.Message)
}
// errors.Is 和 errors.As(Go 1.13+)
if errors.Is(err, os.ErrNotExist) {
fmt.Println("文件不存在")
}
var myErr *MyError
if errors.As(err, &myErr) {
fmt.Println("错误码:", myErr.Code)
}包管理
go
// 每个 Go 文件属于一个包
package main // main 包是程序入口
// 导入其他包
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin" // 第三方包
)
// 导出的标识符首字母大写
func PublicFunc() {} // 公开
func privateFunc() {} // 包内私有
// Go Modules 依赖管理
// go mod init myproject # 初始化模块
// go mod tidy # 整理依赖
// go get github.com/xxx/xxx # 安装依赖标准库速览
| 分类 | 常用包 |
|---|---|
| 输入输出 | fmt、io、os、bufio、path/filepath |
| 网络 | net、net/http、net/url |
| 编码 | encoding/json、encoding/xml、encoding/csv |
| 加密 | crypto、crypto/tls |
| 并发 | sync、context、sync/atomic |
| 测试 | testing、net/http/httptest |
| 时间 | time |
| 字符串 | strings、strconv、regexp |
| 数据库 | database/sql |
常用 CLI 命令
bash
go version # 查看版本
go run main.go # 直接运行
go build # 编译为可执行文件
go install # 编译并安装到 GOPATH/bin
go test ./... # 运行所有测试
go test -v -cover # 详细输出 + 覆盖率
go fmt ./... # 格式化代码
go vet ./... # 静态分析
go mod tidy # 整理模块依赖
go mod download # 下载依赖
go env # 查看 Go 环境变量
# 交叉编译示例
GOOS=linux GOARCH=amd64 go build # 编译 Linux 版本
GOOS=windows GOARCH=amd64 go build # 编译 Windows 版本常用第三方库
| 库 | 用途 |
|---|---|
| Gin | 高性能 HTTP Web 框架 |
| Echo | 极简高性能 Web 框架 |
| GORM | ORM 框架 |
| Viper | 配置管理 |
| Zap | 高性能日志库 |
| Cobra | CLI 应用框架 |
| Testify | 测试断言与 Mock |
| Wire | 依赖注入代码生成 |
| gRPC-Go | gRPC 实现 |
适用场景
- 微服务 / API 网关:编译为单一二进制文件,部署极简,内存占用低
- 云原生基础设施:Docker、Kubernetes、Prometheus 等均用 Go 编写
- CLI 工具:跨平台编译,分发方便
- 高并发网络服务:goroutine 轻量级并发,轻松支撑百万连接
- 区块链:以太坊 geth、Hyperledger Fabric 等
- DevOps 工具:Terraform、Consul、etcd 等
不适用场景
- 复杂的 GUI 桌面应用
- 嵌入式系统(资源极端受限场景)
- 对泛型有深度依赖的场景(Go 1.18 已支持泛型,但仍较克制)
作者:yanshaodong