go
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGo 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: Usewith technology:mcp__documentation__fetch_docsfor comprehensive documentation.go
完整参考资料: 如需了解并发模式(工作池、信号量、扇出/扇入)、生产环境就绪、结构化日志、优雅停机、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 sentgo
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 := <-chgo
ch := make(chan int, 10) // 缓冲区大小为10
ch <- 1 // 非阻塞(若缓冲区未填满)
ch <- 2
value := <-chChannel Direction
Channel方向
go
func send(ch chan<- int, value int) { ch <- value } // Send-only
func receive(ch <-chan int) int { return <-ch } // Receive-onlygo
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 dependenciesbash
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
└── Makefilemyproject/
├── cmd/
│ └── server/
│ └── main.go # 入口文件
├── internal/ # 私有包
│ ├── handler/
│ ├── service/
│ └── repository/
├── pkg/ # 公共包
├── go.mod
└── MakefileWhen NOT to Use This Skill
何时不应使用本技能
| Scenario | Use Instead |
|---|---|
| Gin/Fiber/Echo specifics | Framework-specific skills |
| GORM operations | ORM-specific skill |
| gRPC service definition | |
| Testing specifics | |
| 场景 | 替代技能 |
|---|---|
| Gin/Fiber/Echo框架细节 | 框架专属技能 |
| GORM操作 | ORM专属技能 |
| gRPC服务定义 | |
| 测试细节 | |
Anti-Patterns
反模式
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| Not closing channels | Goroutine leaks | Always close when done |
| Ignoring errors | Silent failures | Check every error |
| Goroutine without context | Can't cancel | Pass context.Context |
| Not using defer for cleanup | Resource leaks | Always defer cleanup |
| Panic in production | Process crashes | Return errors |
| Empty interface everywhere | Loses type safety | Use generics (1.18+) |
| Copying mutexes | Undefined behavior | Pass by pointer |
| 反模式 | 危害 | 正确做法 |
|---|---|---|
| 不关闭channels | Goroutine泄漏 | 完成使用后务必关闭 |
| 忽略错误 | 静默失败 | 检查每一个错误 |
| Goroutine不携带context | 无法取消 | 传递context.Context |
| 不使用defer进行清理 | 资源泄漏 | 务必使用defer进行清理 |
| 生产环境中使用Panic | 进程崩溃 | 返回错误 |
| 到处使用空接口 | 失去类型安全性 | 使用泛型(1.18+) |
| 复制互斥锁 | 行为未定义 | 通过指针传递 |
Quick Troubleshooting
快速故障排查
| Issue | Cause | Solution |
|---|---|---|
| "all goroutines are asleep - deadlock!" | Channel deadlock | Check send/receive balance |
| "close of closed channel" | Closing twice | Use sync.Once |
| "concurrent map writes" | Race condition | Use sync.Map or mutex |
| "context deadline exceeded" | Timeout reached | Increase timeout or optimize |
| "assignment to entry in nil map" | Map not initialized | Initialize with make() |
| "nil pointer dereference" | Accessing nil | Check 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