Go 语言中 10 个高频实用写法
以下是 Go 语言中 10 个高频实用写法的示例,涵盖并发控制、错误处理、标准库应用等场景,结合最佳实践和实际案例说明:
一、基础语法
1. 变量声明与类型推断
// 显式声明
var name string = "Go"
// 类型推断(常用)
age := 30
const Pi = 3.14159
场景:局部变量优先用 :=
简化代码。
2. 多返回值与错误处理
func divide(a, b int) (int, error) {if b == 0 {return 0, fmt.Errorf("除数不能为0")}return a / b, nil
}// 调用时显式处理错误
result, err := divide(10, 0)
if err != nil {log.Fatal(err) // 或 return err
}
关键:错误作为值(error-as-value) 是 Go 的核心设计。
二、并发处理
3. Goroutine 与 WaitGroup 同步
var wg sync.WaitGroup
for i := 0; i < 3; i++ {wg.Add(1)go func(id int) {defer wg.Done() // 确保任务完成计数-1fmt.Printf("Goroutine %d 执行\n", id)}(i)
}
wg.Wait() // 阻塞等待所有任务完成
适用场景:批量异步任务协同。
4. Channel 通信与超时控制
ch := make(chan string, 1)
go func() {time.Sleep(2 * time.Second)ch <- "结果"
}()select {
case res := <-ch:fmt.Println(res)
case <-time.After(1 * time.Second): // 超时机制fmt.Println("请求超时")
}
作用:避免 Goroutine 阻塞泄漏。
三、标准库应用
5. HTTP 服务与中间件
// 基础服务
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello, %s", r.URL.Path)
})// 中间件(日志记录)
loggingMiddleware := func(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {log.Println(r.Method, r.URL.Path)next.ServeHTTP(w, r)})
}
http.ListenAndServe(":8080", loggingMiddleware(http.DefaultServeMux))
扩展:结合 context
处理请求超时。
6. JSON 序列化与反序列化
type User struct {Name string `json:"name"`Age int `json:"age"`
}// 序列化
data, _ := json.Marshal(User{"Alice", 25})
fmt.Println(string(data)) // {"name":"Alice","age":25}// 反序列化
var user User
json.Unmarshal(data, &user)
注意:结构体字段标签(Tag)控制 JSON 键名。
四、实用技巧
7. 资源清理与 defer
func readFile(path string) (string, error) {file, err := os.Open(path)if err != nil {return "", err}defer file.Close() // 确保函数返回前关闭文件content, err := io.ReadAll(file)return string(content), err
}
核心:defer
用于资源释放、锁解锁等清理操作。
8. 函数选项模式(Functional Options)
type Server struct {Port intTimeout time.Duration
}type Option func(*Server)func WithPort(port int) Option {return func(s *Server) { s.Port = port }
}func NewServer(opts ...Option) *Server {s := &Server{Port: 8080, Timeout: 30 * time.Second} // 默认值for _, opt := range opts {opt(s) // 应用选项}return s
}// 使用
server := NewServer(WithPort(9000))
优势:优雅处理可选参数,替代冗长的构造函数。
五、高级模式
9. 工作池(Worker Pool)
func worker(id int, jobs <-chan int, results chan<- int) {for job := range jobs {fmt.Printf("Worker %d 处理任务 %d\n", id, job)results <- job * 2}
}func main() {jobs := make(chan int, 10)results := make(chan int, 10)// 启动 3 个 Workerfor 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}
}
适用场景:限制并发数(如数据库连接池)。
10. 依赖注入(结构体组合)
type Logger interface {Log(message string)
}type Service struct {logger Logger
}func NewService(logger Logger) *Service {return &Service{logger: logger}
}func (s *Service) Process() {s.logger.Log("处理开始")// 业务逻辑
}
作用:提升可测试性,解耦组件依赖。
附:综合示例(文件处理 + 并发)
// 并发读取多个文件内容并合并
func mergeFiles(paths []string) (string, error) {var wg sync.WaitGroupresults := make(chan string, len(paths))errCh := make(chan error, 1)for _, path := range paths {wg.Add(1)go func(p string) {defer wg.Done()content, err := os.ReadFile(p)if err != nil {select {case errCh <- err: // 仅发送第一个错误default:}return}results <- string(content)}(path)}go func() {wg.Wait()close(results)close(errCh)}()var builder strings.Builderfor content := range results {builder.WriteString(content)}if err, ok := <-errCh; ok {return "", err}return builder.String(), nil
}
技巧:通过 select
+ errCh
避免并发错误覆盖。
最佳实践总结
- 并发安全
- 共享数据用
sync.Mutex
或atomic
包 - Channel 优先于共享内存
- 共享数据用
- 错误处理
- 错误需显式检查,避免
_
忽略 - 自定义错误类型提供上下文(如
fmt.Errorf("读取 %s 失败: %w", path, err)
)
- 错误需显式检查,避免
- 性能优化
- 大结构体用指针传递(
func (u *User) Update()
) - 高频创建对象考虑
sync.Pool
- 大结构体用指针传递(
- 代码简洁
- 接口定义小而非大(如
io.Reader
) - 避免嵌套过深,尽早返回错误
- 接口定义小而非大(如
完整示例可参考来源:Go 基础语法 | 并发模式实战