Golang 学习指南
目录
基础语法
数据类型
go
// 基本类型
var (
intNum int = 42
floatNum float64 = 3.14
str string = "Hello"
boolValue bool = true
)
// 复合类型
type Person struct {
Name string
Age int
}
// 数组和切片
var arr [5]int
slice := []int{1, 2, 3}
// Map
m := map[string]int{
"apple": 1,
"banana": 2,
}
// 类型转换
i := 42
f := float64(i)
s := strconv.Itoa(i)说明:
- 基本数据类型
- 复合类型
- 数组和切片
- 类型转换
控制流程
go
// 条件语句
if age >= 18 {
fmt.Println("成年人")
} else if age >= 12 {
fmt.Println("青少年")
} else {
fmt.Println("儿童")
}
// 循环语句
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// range 循环
for index, value := range slice {
fmt.Printf("索引: %d, 值: %d\n", index, value)
}
// switch 语句
switch day {
case "Monday":
fmt.Println("星期一")
case "Tuesday":
fmt.Println("星期二")
default:
fmt.Println("其他")
}说明:
- 条件语句
- 循环语句
- range 循环
- switch 语句
函数
go
// 函数定义
func add(a, b int) int {
return a + b
}
// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("除数不能为0")
}
return a / b, nil
}
// 可变参数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
// 匿名函数
func() {
fmt.Println("匿名函数")
}()
// 闭包
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}说明:
- 函数定义
- 多返回值
- 可变参数
- 匿名函数
- 闭包
包管理
go
// 包声明
package main
// 导入包
import (
"fmt"
"math"
"time"
)
// 自定义包
// mypackage/math.go
package mypackage
func Add(a, b int) int {
return a + b
}
// 使用包
import "mypackage"
result := mypackage.Add(1, 2)说明:
- 包声明
- 包导入
- 自定义包
- 包组织
面向对象
结构体
go
// 结构体定义
type Person struct {
Name string
Age int
Address struct {
City string
Country string
}
}
// 创建实例
p := Person{
Name: "John",
Age: 25,
}
// 访问字段
fmt.Println(p.Name)
p.Age = 26说明:
- 结构体定义
- 实例创建
- 字段访问
- 嵌套结构体
接口
go
// 接口定义
type Animal interface {
Speak() string
Move() string
}
// 实现接口
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof!"
}
func (d Dog) Move() string {
return "Running"
}
// 使用接口
var a Animal = Dog{Name: "Buddy"}
fmt.Println(a.Speak())说明:
- 接口定义
- 接口实现
- 接口使用
- 空接口
方法
go
// 方法定义
func (p Person) SayHello() {
fmt.Printf("Hello, I'm %s\n", p.Name)
}
// 指针接收者
func (p *Person) SetAge(age int) {
p.Age = age
}
// 方法集
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}说明:
- 方法定义
- 指针接收者
- 方法集
- 接口方法
组合
go
// 结构体组合
type Employee struct {
Person
Salary float64
}
// 接口组合
type ReadWriter interface {
Reader
Writer
}
// 使用组合
e := Employee{
Person: Person{Name: "John"},
Salary: 5000,
}
e.SayHello()说明:
- 结构体组合
- 接口组合
- 方法继承
- 组合vs继承
并发编程
Goroutine
go
// 创建 Goroutine
go func() {
fmt.Println("Goroutine 运行中")
}()
// 等待 Goroutine
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Goroutine 完成")
}()
wg.Wait()说明:
- Goroutine 创建
- Goroutine 同步
- Goroutine 通信
- Goroutine 管理
Channel
go
// 创建 Channel
ch := make(chan int)
// 发送数据
go func() {
ch <- 42
}()
// 接收数据
value := <-ch
// 带缓冲的 Channel
bufferedCh := make(chan int, 3)
bufferedCh <- 1
bufferedCh <- 2
bufferedCh <- 3说明:
- Channel 创建
- 数据发送
- 数据接收
- 缓冲 Channel
Select
go
// Select 语句
select {
case msg1 := <-ch1:
fmt.Println("收到 ch1:", msg1)
case msg2 := <-ch2:
fmt.Println("收到 ch2:", msg2)
case <-time.After(time.Second):
fmt.Println("超时")
default:
fmt.Println("没有数据")
}说明:
- Select 语法
- 多路复用
- 超时处理
- 默认分支
Context
go
// 创建 Context
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 使用 Context
go func(ctx context.Context) {
select {
case <-ctx.Done():
fmt.Println("Context 取消")
case <-time.After(2 * time.Second):
fmt.Println("操作完成")
}
}(ctx)说明:
- Context 创建
- Context 传递
- Context 取消
- Context 超时
标准库
文件操作
go
// 文件读写
data := []byte("Hello, World!")
err := ioutil.WriteFile("file.txt", data, 0644)
if err != nil {
log.Fatal(err)
}
content, err := ioutil.ReadFile("file.txt")
if err != nil {
log.Fatal(err)
}
// 文件操作
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()说明:
- 文件读写
- 文件操作
- 目录操作
- 文件权限
网络编程
go
// HTTP 服务器
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
})
http.ListenAndServe(":8080", nil)
// HTTP 客户端
resp, err := http.Get("http://api.example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()说明:
- HTTP 服务器
- HTTP 客户端
- TCP 编程
- WebSocket
并发工具
go
// Mutex
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
// RWMutex
var rwmu sync.RWMutex
rwmu.RLock()
defer rwmu.RUnlock()
// Once
var once sync.Once
once.Do(func() {
fmt.Println("只执行一次")
})说明:
- Mutex
- RWMutex
- Once
- WaitGroup
数据处理
go
// JSON 处理
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
user := User{Name: "John", Age: 25}
data, err := json.Marshal(user)
if err != nil {
log.Fatal(err)
}
// 数据库操作
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
log.Fatal(err)
}
defer db.Close()说明:
- JSON 处理
- 数据库操作
- 数据验证
- 数据转换
最佳实践
1. 代码规范
- 遵循 Go 代码规范
- 使用 gofmt
- 编写单元测试
- 代码审查
2. 性能优化
- 使用 sync.Pool
- 避免内存分配
- 使用 pprof
- 并发优化
3. 安全实践
- 输入验证
- 错误处理
- 资源管理
- 安全配置
学习资源
官方文档
视频课程
- 慕课网
- 极客时间
- B站技术区
- YouTube 技术频道
工具推荐
错误处理
go
// 错误处理最佳实践
func processFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return fmt.Errorf("打开文件失败: %w", err)
}
defer file.Close()
// 处理文件
return nil
}
// 自定义错误
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
// 错误包装
if err != nil {
return fmt.Errorf("处理失败: %w", err)
}说明:
- 错误处理最佳实践
- 自定义错误类型
- 错误包装
- 错误链追踪
测试
go
// 单元测试
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"正数相加", 1, 2, 3},
{"负数相加", -1, -2, -3},
{"零值相加", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; 期望 %d", tt.a, tt.b, result, tt.expected)
}
})
}
}
// 基准测试
func BenchmarkConcat(b *testing.B) {
var str string
for i := 0; i < b.N; i++ {
str += "x"
}
}
// 测试覆盖率
// go test -cover
// go test -coverprofile=coverage.out
// go tool cover -html=coverage.out说明:
- 单元测试
- 基准测试
- 测试覆盖率
- 测试最佳实践
性能优化
go
// 内存优化
// 使用对象池
var pool = sync.Pool{
New: func() interface{} {
return new(Buffer)
},
}
// 并发优化
// 使用工作池
func workerPool(jobs <-chan int, results chan<- int) {
for j := range jobs {
results <- j * 2
}
}
// 使用 sync.Map
var m sync.Map
m.Store("key", "value")
value, ok := m.Load("key")
// 使用 atomic 包
var counter int64
atomic.AddInt64(&counter, 1)说明:
- 内存优化
- 并发优化
- 原子操作
- 性能分析工具
项目结构规范
project/
├── cmd/ # 主程序入口
│ └── main.go
├── internal/ # 私有应用代码
│ ├── api/ # API 处理
│ ├── service/ # 业务逻辑
│ └── repository/ # 数据访问
├── pkg/ # 可共享的库代码
│ ├── utils/ # 工具函数
│ └── models/ # 数据模型
├── configs/ # 配置文件
├── scripts/ # 构建和部署脚本
├── test/ # 测试文件
├── docs/ # 文档
├── go.mod # 依赖管理
└── README.md # 项目说明说明:
- 标准项目结构
- 代码组织
- 依赖管理
- 文档规范
开发工具
- GoLand: JetBrains 的 Go IDE
- VS Code + Go 插件
- Delve: Go 调试器
- Go Modules: 依赖管理
- Go Lint: 代码检查
- Go Test: 测试工具
- Go Profiling: 性能分析