go

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Go Core Knowledge

Go核心知识

Full Reference: See advanced.md for concurrency patterns (worker pool, semaphore, fan-out/fan-in), production readiness, structured logging, graceful shutdown, context usage, health checks, testing patterns, HTTP client best practices, and database connection pooling.
Deep Knowledge: Use
mcp__documentation__fetch_docs
with technology:
go
for comprehensive documentation.
完整参考资料: 如需了解并发模式(工作池、信号量、扇出/扇入)、生产环境就绪、结构化日志、优雅停机、context使用、健康检查、测试模式、HTTP客户端最佳实践以及数据库连接池等内容,请查看advanced.md
深度知识: 使用
mcp__documentation__fetch_docs
工具并指定技术为
go
,可获取全面的文档资料。

Goroutines and Concurrency

Goroutines与并发

Basic Goroutine

基础Goroutine

go
func sayHello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func main() {
    go sayHello("World")  // Run concurrently
    time.Sleep(100 * time.Millisecond)
}
go
func sayHello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func main() {
    go sayHello("World")  // 并发运行
    time.Sleep(100 * time.Millisecond)
}

Core Principle

核心原则

"Do not communicate by sharing memory; instead, share memory by communicating."

“不要通过共享内存来通信;相反,要通过通信来共享内存。”

Channels

Channels

Unbuffered Channel

无缓冲Channel

go
c := make(chan int)  // Unbuffered channel

go func() {
    result := compute()
    c <- result  // Send - blocks until received
}()

value := <-c  // Receive - blocks until sent
go
c := make(chan int)  // 无缓冲Channel

go func() {
    result := compute()
    c <- result  // 发送 - 直到接收端就绪才会解除阻塞
}()

value := <-c  // 接收 - 直到发送端就绪才会解除阻塞

Buffered Channel

有缓冲Channel

go
ch := make(chan int, 10)  // Buffer size 10

ch <- 1  // Non-blocking (if buffer not full)
ch <- 2

value := <-ch
go
ch := make(chan int, 10)  // 缓冲区大小为10

ch <- 1  // 非阻塞(若缓冲区未填满)
ch <- 2

value := <-ch

Channel Direction

Channel方向

go
func send(ch chan<- int, value int) { ch <- value }   // Send-only
func receive(ch <-chan int) int { return <-ch }       // Receive-only
go
func send(ch chan<- int, value int) { ch <- value }   // 仅发送
func receive(ch <-chan int) int { return <-ch }       // 仅接收

Select Statement

Select语句

go
select {
case msg := <-ch1:
    fmt.Println("Received from ch1:", msg)
case ch2 <- value:
    fmt.Println("Sent to ch2")
case <-time.After(5 * time.Second):
    fmt.Println("Timeout")
default:
    fmt.Println("No communication ready")
}

go
select {
case msg := <-ch1:
    fmt.Println("Received from ch1:", msg)
case ch2 <- value:
    fmt.Println("Sent to ch2")
case <-time.After(5 * time.Second):
    fmt.Println("Timeout")
default:
    fmt.Println("No communication ready")
}

Interfaces

接口

Interface Definition

接口定义

go
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// Embedded interfaces
type ReadWriter interface {
    Reader
    Writer
}
go
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// 嵌入接口
type ReadWriter interface {
    Reader
    Writer
}

Implicit Implementation

隐式实现

go
type MyReader struct {
    data []byte
    pos  int
}

// No "implements" keyword needed
func (r *MyReader) Read(p []byte) (n int, err error) {
    if r.pos >= len(r.data) {
        return 0, io.EOF
    }
    n = copy(p, r.data[r.pos:])
    r.pos += n
    return n, nil
}
go
type MyReader struct {
    data []byte
    pos  int
}

// 无需使用"implements"关键字
func (r *MyReader) Read(p []byte) (n int, err error) {
    if r.pos >= len(r.data) {
        return 0, io.EOF
    }
    n = copy(p, r.data[r.pos:])
    r.pos += n
    return n, nil
}

Type Assertion and Switch

类型断言与类型切换

go
// Safe check
str, ok := value.(string)
if ok {
    fmt.Printf("string value: %q\n", str)
}

// Type switch
switch v := value.(type) {
case bool:
    fmt.Printf("boolean %t\n", v)
case int:
    fmt.Printf("integer %d\n", v)
default:
    fmt.Printf("unexpected type %T\n", v)
}

go
// 安全检查
str, ok := value.(string)
if ok {
    fmt.Printf("string value: %q\n", str)
}

// 类型切换
switch v := value.(type) {
case bool:
    fmt.Printf("boolean %t\n", v)
case int:
    fmt.Printf("integer %d\n", v)
default:
    fmt.Printf("unexpected type %T\n", v)
}

Error Handling

错误处理

Standard Pattern

标准模式

go
func doSomething() error {
    if err := step1(); err != nil {
        return fmt.Errorf("step1 failed: %w", err)
    }
    return nil
}
go
func doSomething() error {
    if err := step1(); err != nil {
        return fmt.Errorf("step1 failed: %w", err)
    }
    return nil
}

Custom Error Types

自定义错误类型

go
type PathError struct {
    Op   string
    Path string
    Err  error
}

func (e *PathError) Error() string {
    return e.Op + " " + e.Path + ": " + e.Err.Error()
}

func (e *PathError) Unwrap() error {
    return e.Err
}
go
type PathError struct {
    Op   string
    Path string
    Err  error
}

func (e *PathError) Error() string {
    return e.Op + " " + e.Path + ": " + e.Err.Error()
}

func (e *PathError) Unwrap() error {
    return e.Err
}

Error Wrapping (Go 1.13+)

错误包装(Go 1.13+)

go
// Wrap error with context
return fmt.Errorf("failed to open config: %w", err)

// Check wrapped errors
if errors.Is(err, os.ErrNotExist) {
    // Handle file not found
}

// Get underlying error type
var pathErr *os.PathError
if errors.As(err, &pathErr) {
    fmt.Println("Path:", pathErr.Path)
}

go
// 为错误添加上下文信息
return fmt.Errorf("failed to open config: %w", err)

// 检查包装后的错误
if errors.Is(err, os.ErrNotExist) {
    // 处理文件不存在的情况
}

// 获取底层错误类型
var pathErr *os.PathError
if errors.As(err, &pathErr) {
    fmt.Println("Path:", pathErr.Path)
}

Structs and Methods

结构体与方法

go
type User struct {
    ID    int64  `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

// Value receiver - cannot modify original
func (u User) FullName() string { return u.Name }

// Pointer receiver - can modify original
func (u *User) SetName(name string) { u.Name = name }

// Constructor pattern
func NewUser(name, email string) *User {
    return &User{
        ID:    generateID(),
        Name:  name,
        Email: email,
    }
}

go
type User struct {
    ID    int64  `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

// 值接收器 - 无法修改原对象
func (u User) FullName() string { return u.Name }

// 指针接收器 - 可以修改原对象
func (u *User) SetName(name string) { u.Name = name }

// 构造函数模式
func NewUser(name, email string) *User {
    return &User{
        ID:    generateID(),
        Name:  name,
        Email: email,
    }
}

Generics (Go 1.18+)

泛型(Go 1.18+)

go
func Map[T, U any](slice []T, fn func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = fn(v)
    }
    return result
}

type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

// Type constraints
type Number interface {
    ~int | ~int32 | ~int64 | ~float32 | ~float64
}

func Sum[T Number](numbers []T) T {
    var sum T
    for _, n := range numbers {
        sum += n
    }
    return sum
}

go
func Map[T, U any](slice []T, fn func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = fn(v)
    }
    return result
}

type Stack[T any] struct {
    items []T
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

// 类型约束
type Number interface {
    ~int | ~int32 | ~int64 | ~float32 | ~float64
}

func Sum[T Number](numbers []T) T {
    var sum T
    for _, n := range numbers {
        sum += n
    }
    return sum
}

Modules

模块

go.mod

go.mod

go
module github.com/user/myproject

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1
)
go
module github.com/user/myproject

go 1.21

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

Common Commands

常用命令

bash
go mod init github.com/user/project  # Initialize module
go mod tidy                          # Add missing, remove unused
go get package@version               # Add/update dependency
go list -m all                       # List all dependencies

bash
go mod init github.com/user/project  # 初始化模块
go mod tidy                          # 添加缺失依赖,移除未使用依赖
go get package@version               # 添加/更新依赖
go list -m all                       # 列出所有依赖

Project Structure

项目结构

myproject/
├── cmd/
│   └── server/
│       └── main.go        # Entry point
├── internal/              # Private packages
│   ├── handler/
│   ├── service/
│   └── repository/
├── pkg/                   # Public packages
├── go.mod
└── Makefile

myproject/
├── cmd/
│   └── server/
│       └── main.go        # 入口文件
├── internal/              # 私有包
│   ├── handler/
│   ├── service/
│   └── repository/
├── pkg/                   # 公共包
├── go.mod
└── Makefile

When NOT to Use This Skill

何时不应使用本技能

ScenarioUse Instead
Gin/Fiber/Echo specificsFramework-specific skills
GORM operationsORM-specific skill
gRPC service definition
api-design-grpc
skill
Testing specifics
testing-go
skill

场景替代技能
Gin/Fiber/Echo框架细节框架专属技能
GORM操作ORM专属技能
gRPC服务定义
api-design-grpc
技能
测试细节
testing-go
技能

Anti-Patterns

反模式

Anti-PatternWhy It's BadCorrect Approach
Not closing channelsGoroutine leaksAlways close when done
Ignoring errorsSilent failuresCheck every error
Goroutine without contextCan't cancelPass context.Context
Not using defer for cleanupResource leaksAlways defer cleanup
Panic in productionProcess crashesReturn errors
Empty interface everywhereLoses type safetyUse generics (1.18+)
Copying mutexesUndefined behaviorPass by pointer

反模式危害正确做法
不关闭channelsGoroutine泄漏完成使用后务必关闭
忽略错误静默失败检查每一个错误
Goroutine不携带context无法取消传递context.Context
不使用defer进行清理资源泄漏务必使用defer进行清理
生产环境中使用Panic进程崩溃返回错误
到处使用空接口失去类型安全性使用泛型(1.18+)
复制互斥锁行为未定义通过指针传递

Quick Troubleshooting

快速故障排查

IssueCauseSolution
"all goroutines are asleep - deadlock!"Channel deadlockCheck send/receive balance
"close of closed channel"Closing twiceUse sync.Once
"concurrent map writes"Race conditionUse sync.Map or mutex
"context deadline exceeded"Timeout reachedIncrease timeout or optimize
"assignment to entry in nil map"Map not initializedInitialize with make()
"nil pointer dereference"Accessing nilCheck for nil before use

问题原因解决方案
"all goroutines are asleep - deadlock!"Channel死锁检查发送/接收平衡
"close of closed channel"重复关闭使用sync.Once
"concurrent map writes"竞态条件使用sync.Map或互斥锁
"context deadline exceeded"超时增加超时时间或优化性能
"assignment to entry in nil map"Map未初始化使用make()初始化
"nil pointer dereference"访问nil指针使用前检查是否为nil

Reference Documentation

参考文档

  • Concurrency
  • Interfaces
  • Error Handling
  • Concurrency
  • Interfaces
  • Error Handling