📚 前言
欢迎学习Go语言!这份教材假设您是编程零基础,从最基本的概念开始讲解。Go语言(也称为Golang)由Google开发,简单、高效、并发能力强,适合后端开发、系统编程和云计算。
学习建议:
- 环境准备:安装Go 1.21+(官网:https://go.dev/dl/),推荐VS Code编辑器 + Go扩展。
- 学习方法:每章后完成练习,动手敲代码。
- 时间安排:每天1-2小时,3-4个月完成。
- 资源:Go官方游乐场(play.golang.org)用于在线测试代码。
第1章:Go语言基础与环境搭建
1.1 什么是Go语言?
Go是一种静态类型、编译型语言,诞生于2009年。特点:
- 简单:语法简洁,像Python一样易读。
- 高效:运行速度接近C++。
- 并发:内置goroutine支持多任务。
- 用途:Web服务器、工具脚本、云计算(Kubernetes就是用Go写的)。
1.2 安装与环境配置
-
下载安装:
- Windows:下载MSI安装器,安装后自动配置环境变量。
- macOS:下载PKG或用Homebrew
brew install go
。 - Linux:下载tar.gz,解压到
/usr/local/go
,添加环境变量。
-
配置环境变量(手动):
GOROOT
:Go安装目录(例如/usr/local/go
)。GOPATH
:工作目录(例如$HOME/go
)。PATH
:添加$GOROOT/bin
和$GOPATH/bin
。
示例(在
.bashrc
或.zshrc
中):bashexport GOROOT=/usr/local/go export GOPATH=$HOME/go export PATH=$PATH:$GOROOT/bin:$GOPATH/bin source ~/.bashrc
-
验证:
bashgo version # 输出 go1.21.x go env # 查看配置
1.3 第一个程序
创建hello.go
:
go
package main // 每个Go文件必须声明包
import "fmt" // 导入fmt包,用于打印
func main() { // main函数是程序入口
fmt.Println("Hello, Go!") // 打印输出
}
运行:
bash
go run hello.go # 直接运行
go build hello.go # 编译成可执行文件
./hello # 执行(Windows为hello.exe)
练习:修改程序,输入你的名字并打印问候语。
第2章:变量、数据类型与运算符
2.1 变量声明
Go是静态类型语言,变量必须有类型。
go
var name string = "Alice" // 显式声明
age := 25 // 短变量声明(自动推导类型)
var ( // 批量声明
x int
y float64 = 3.14
)
2.2 基本数据类型
- 整数:int(平台相关,通常64位)、int8、int16、int32、int64、uint(无符号)。
- 浮点:float32、float64。
- 布尔:bool(true/false)。
- 字符串:string(不可变,UTF-8编码)。
- 常量:const pi = 3.14159(编译时确定)。
示例:
go
var isActive bool = true
fmt.Println("Pi:", pi)
2.3 运算符
- 算术:+、-、*、/、%(取余)。
- 比较:==、!=、>、<、>=、<=。
- 逻辑:&&(与)、||(或)、!(非)。
- 位运算:&、|、^、<<、>>(了解即可)。
示例:
go
a := 10
b := 3
sum := a + b // 13
mod := a % b // 1
fmt.Println(sum > mod) // true
练习:编写程序计算圆的面积(面积 = pi * r^2),r从用户输入。
第3章:控制结构
3.1 条件语句
go
if age >= 18 {
fmt.Println("Adult")
} else if age >= 13 {
fmt.Println("Teen")
} else {
fmt.Println("Child")
}
- 支持初始化语句:
if x := 10; x > 5 { ... }
。
3.2 循环语句
Go只有for循环:
go
// 无限循环
for {
// ...
break // 退出
}
// 传统for
for i := 0; i < 5; i++ {
fmt.Println(i) // 0到4
}
// 范围循环(类似foreach)
nums := []int{1,2,3}
for index, value := range nums {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
3.3 switch语句
go
day := "Monday"
switch day {
case "Monday":
fmt.Println("Start of week")
case "Friday":
fmt.Println("Weekend soon")
default:
fmt.Println("Midweek")
}
- 支持fallthrough(显式继续下一个case)。
练习:实现一个简单计算器,支持+、-、*、/,使用switch处理操作符。
第4章:函数与错误处理
4.1 函数定义
go
func add(a int, b int) int { // 参数类型后置,返回类型
return a + b
}
// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
// 调用
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
}
4.2 匿名函数与闭包
go
func main() {
multiply := func(x, y int) int { return x * y }
fmt.Println(multiply(2, 3)) // 6
// 闭包
counter := func() func() int {
i := 0
return func() int {
i++
return i
}
}()
fmt.Println(counter()) // 1
fmt.Println(counter()) // 2
}
4.3 defer、panic与recover
- defer:函数结束时执行(常用于清理)。
go
func main() {
defer fmt.Println("Deferred") // 最后执行
fmt.Println("Main")
}
- panic:抛出异常。
- recover:捕获panic。
go
func safeDivide(a, b int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
if b == 0 {
panic("division by zero")
}
fmt.Println(a / b)
}
练习:编写一个函数,读取文件内容,使用defer关闭文件。
第5章:数组、切片与Map
5.1 数组
固定长度,值类型。
go
var arr [3]int = [3]int{1, 2, 3}
fmt.Println(arr[0]) // 1
// 多维数组
matrix := [2][2]int{{1,2}, {3,4}}
5.2 切片(Slice)
动态数组,引用类型。
go
slice := []int{1, 2, 3} // 切片字面量
slice = append(slice, 4) // 添加元素
sub := slice[1:3] // 子切片(2,3)
fmt.Println(len(slice), cap(slice)) // 长度4,容量4
- make创建:
make([]int, 3, 5)
(长度3,容量5)。
5.3 Map(字典)
键值对,无序。
go
m := make(map[string]int)
m["age"] = 25
delete(m, "age")
// 检查存在
val, ok := m["age"]
if ok {
fmt.Println(val)
}
// 遍历
for key, value := range m {
fmt.Printf("%s: %d\n", key, value)
}
练习:实现一个学生成绩管理系统,使用Map存储姓名-分数,使用切片排序输出。
第6章:结构体、方法与接口
6.1 结构体(Struct)
自定义类型。
go
type Person struct {
Name string
Age int
}
p := Person{Name: "Bob", Age: 30}
p.Age = 31 // 修改字段
fmt.Println(p) // {Bob 31}
6.2 方法
函数绑定到结构体。
go
func (p Person) Greet() string { // 值接收者
return "Hello, " + p.Name
}
func (p *Person) Birthday() { // 指针接收者(可修改)
p.Age++
}
fmt.Println(p.Greet()) // Hello, Bob
p.Birthday()
fmt.Println(p.Age) // 32
6.3 接口
定义行为。
go
type Shape interface {
Area() float64
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func PrintArea(s Shape) {
fmt.Println(s.Area())
}
PrintArea(Circle{Radius: 5}) // 78.5
- 空接口
interface{}
:任意类型(类似any)。
练习:定义Rectangle结构体,实现Shape接口,计算面积和周长。
第7章:并发编程
Go的核心优势:轻量级线程(goroutine)。
7.1 Goroutine
go
func task() {
fmt.Println("Task running")
}
func main() {
go task() // 异步执行
time.Sleep(time.Second) // 等待
}
7.2 Channel
goroutine间通信。
go
ch := make(chan int) // 无缓冲channel
go func() {
ch <- 42 // 发送
close(ch)
}()
val := <-ch // 接收
fmt.Println(val)
- 缓冲channel:
make(chan int, 10)
。
7.3 select与同步
go
select {
case v := <-ch1:
fmt.Println(v)
case v := <-ch2:
fmt.Println(v)
default:
fmt.Println("No data")
}
- sync包:Mutex、WaitGroup。
go
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// 任务
}()
wg.Wait()
练习:使用goroutine和channel实现生产者-消费者模式。
第8章:包管理与模块
8.1 包(Package)
- 每个目录是一个包。
- 导入:
import "fmt"
或import mypkg "github.com/user/mypkg"
。
8.2 Go Modules
现代化依赖管理(Go 1.11+)。
bash
go mod init example.com/myapp # 初始化
go get github.com/gin-gonic/gin # 添加依赖
go mod tidy # 清理
8.3 标准库概览
- fmt:格式化I/O。
- os:系统操作。
- net/http:HTTP客户端/服务器。
- encoding/json:JSON处理。
示例:简单HTTP服务器。
go
import "net/http"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, Web!")
})
http.ListenAndServe(":8080", nil)
}
练习:创建一个包,实现数学工具函数,并导入到主程序。
第9章:错误处理、测试与性能优化
9.1 高级错误处理
使用errors包或自定义错误类型。
go
type MyError struct {
Msg string
}
func (e *MyError) Error() string {
return e.Msg
}
9.2 测试
文件以_test.go
结尾。
go
// math_test.go
func TestAdd(t *testing.T) {
if add(2, 3) != 5 {
t.Error("Expected 5")
}
}
运行:go test
。
基准测试:
go
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
add(2, 3)
}
}
9.3 性能优化
- 使用pprof:
go tool pprof
分析CPU/内存。 - 避免不必要分配。
- 并发优化:减少锁争用。
练习:为上一章的包编写单元测试和基准测试。
第10章:实战项目与进阶主题
10.1 实战项目:RESTful API服务器
使用Gin框架 + GORM(数据库)。
- 安装:
go get github.com/gin-gonic/gin
、go get gorm.io/gorm
。 - 结构:用户CRUD API。
go
// main.go
import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"gorm.io/driver/sqlite"
)
type User struct {
gorm.Model
Name string
}
func main() {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
r := gin.Default()
r.GET("/users", func(c *gin.Context) {
var users []User
db.Find(&users)
c.JSON(200, users)
})
r.POST("/users", func(c *gin.Context) {
var user User
c.BindJSON(&user)
db.Create(&user)
c.JSON(200, user)
})
r.Run(":8080")
}
扩展:添加认证(JWT)、日志。
10.2 进阶主题
- 反射(reflect包):动态类型检查。
- gRPC:RPC框架。
- 微服务:结合Docker/Kubernetes。
- WebAssembly:Go编译到浏览器。
10.3 部署与CI/CD
- Docker:编写Dockerfile,构建镜像。
- GitHub Actions:自动化测试/部署。
最终项目:构建一个完整的博客系统,包括前后端分离(Go后端 + 简单HTML前端)。
📚 推荐学习资源
- 官方:https://go.dev/learn/(教程)、https://go.dev/doc/effective_go(最佳实践)。
- 书籍:《The Go Programming Language》(入门经典)、《Go Web编程》(实战)。
- 视频:Udemy "Go: The Complete Developer's Guide"、YouTube "Gopher Academy"。
- 练习平台:LeetCode(Go标签)、Exercism.io Go轨道。
- 社区:Reddit r/golang、Stack Overflow。