Skills Plugins MCP Prompt Model 博客 我的中心

golang-patterns

用于构建健壮、高效且可维护的Go应用程序的惯用Go模式、最佳实践和约定。

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-zh-cn-skills-golang-patterns-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name golang-patterns description 用于构建健壮、高效且可维护的Go应用程序的惯用Go模式、最佳实践和约定。 origin ECC Go 开发模式 用于构建健壮、高效和可维护应用程序的惯用 Go 模式与最佳实践。 何时激活 编写新的 Go 代码时 审查 Go 代码时 重构现有 Go 代码时 设计 Go 包/模块时 核心原则 1. 简洁与清晰 Go 推崇简洁而非精巧。代码应该显而易见且易于阅读。 // Good: Clear and direct func GetUser (id string ) (*User, error ) { user, err := db.FindUser(id) if err != nil { return nil , fmt.Errorf( "get user %s: %w" , id, err) } return user, nil } // Bad: Overly clever func GetUser (id string ) (*User, error ) { return func () (*User, error ) { if u, e := db.FindUser(id); e == nil { return u, nil } else { return nil , e } }() } 2. 让零值变得有用 设计类型时,应使其零值无需初始化即可立即使用。 // Good: Zero value is useful type Counter struct { mu sync.Mutex count int // zero value is 0, ready to use } func (c *Counter) Inc() { c.mu.Lock() c.count++ c.mu.Unlock() } // Good: bytes.Buffer works with zero value var buf bytes.Buffer buf.WriteString( "hello" ) // Bad: Requires initialization type BadCounter struct { counts map [ string ] int // nil map will panic } 3. 接受接口,返回结构体 函数应该接受接口参数并返回具体类型。 // Good: Accepts interface, returns concrete type func ProcessData (r io.Reader) (*Result, error ) { data, err := io.ReadAll(r) if err != nil { return nil , err } return &Result{Data: data}, nil } // Bad: Returns interface (hides implementation details unnecessarily) func ProcessData (r io.Reader) (io.Reader, error ) { // ... } 错误处理模式 带上下文的错误包装 // Good: Wrap errors with context func LoadConfig (path string ) (*Config, error ) { data, err := os.ReadFile(path) if err != nil { return nil , fmt.Errorf( "load config %s: %w" , path, err) } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil , fmt.Errorf( "parse config %s: %w" , path, err) } return &cfg, nil } 自定义错误类型 // Define domain-specific errors type ValidationError struct { Field string Message string } func (e *ValidationError) Error() string { return fmt.Sprintf( "validation failed on %s: %s" , e.Field, e.Message) } // Sentinel errors for common cases var ( ErrNotFound = errors.New( "resource not found" ) ErrUnauthorized = errors.New( "unauthorized" ) ErrInvalidInput = errors.New( "invalid input" ) ) 使用 errors.Is 和 errors.As 检查错误 func HandleError (err error ) { // Check for specific error if errors.Is(err, sql.ErrNoRows) { log.Println( "No records found" ) return } // Check for error type var validationErr *ValidationError if errors.As(err, &validationErr) { log.Printf( "Validation error on field %s: %s" , validationErr.Field, validationErr.Message) return } // Unknown error log.Printf( "Unexpected error: %v" , err) } 永不忽略错误 // Bad: Ignoring error with blank identifier result, _ := doSomething() // Good: Handle or explicitly document why it's safe to ignore result, err := doSomething() if err != nil { return err } // Acceptable: When error truly doesn't matter (rare) _ = writer.Close() // Best-effort cleanup, error logged elsewhere 并发模式 工作池 func WorkerPool (jobs <- chan Job, results chan <- Result, numWorkers int ) { var wg sync.WaitGroup for i := 0 ; i < numWorkers; i++ { wg.Add( 1 ) go func () { defer wg.Done() for job := range jobs { results <- process(job) } }() } wg.Wait() close (results) } 用于取消和超时的 Context func FetchWithTimeout (ctx context.Context, url string ) ([] byte , error ) { ctx, cancel := context.WithTimeout(ctx, 5 *time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET" , url, nil ) if err != nil { return nil , fmt.Errorf( "create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return nil , fmt.Errorf( "fetch %s: %w" , url, err) } defer resp.Body.Close() return io.ReadAll(resp.Body) } 优雅关闭 func GracefulShutdown (server *http.Server) { quit := make ( chan os.Signal, 1 ) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println( "Shutting down server..." ) ctx, cancel := context.WithTimeout(context.Background(), 30 *time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { log.Fatalf( "Server forced to shutdown: %v" , err) } log.Println( "Server exited" ) } 用于协调 Goroutine 的 errgroup import "golang.org/x/sync/errgroup" func FetchAll (ctx context.Context, urls [] string ) ([][] byte , error ) { g, ctx := errgroup.WithContext(ctx) results := make ([][] byte , len (urls)) for i, url := range urls { i, url := i, url // Capture loop variables g.Go( func () error { data, err := FetchWithTimeout(ctx, url) if err != nil { return err } results[i] = data return nil }) } if err := g.Wait(); err != nil { return nil , err } return results, nil } 避免 Goroutine 泄漏 // Bad: Goroutine leak if context is cancelled func leakyFetch (ctx context.Context, url string ) <- chan [] byte { ch := make ( chan [] byte ) go func () { data, _ := fetch(url) ch <- data // Blocks forever if no receiver }() return ch } // Good: Properly handles cancellation func safeFetch (ctx context.Context, url string ) <- chan [] byte { ch := make ( chan [] byte , 1 ) // Buffered channel go func () { data, err := fetch(url) if err != nil { return } select { case ch <- data: case <-ctx.Done(): } }() return ch } 接口设计 小而专注的接口 // Good: Single-method interfaces type Reader interface { Read(p [] byte ) (n int , err error ) } type Writer interface { Write(p [] byte ) (n int , err error ) } type Closer interface { Close() error } // Compose interfaces as needed type ReadWriteCloser interface { Reader Writer Closer } 在接口使用处定义接口 // In the consumer package, not the provider package service // UserStore defines what this service needs type UserStore interface { GetUser(id string ) (*User, error ) SaveUser(user *User) error } type Service struct { store UserStore } // Concrete implementation can be in another package // It doesn't need to know about this interface 使用类型断言实现可选行为 type Flusher interface { Flush() error } func WriteAndFlush (w io.Writer, data [] byte ) error { if _, err := w.Write(data); err != nil { return err } // Flush if supported if f, ok := w.(Flusher); ok { return f.Flush() } return nil } 包组织 标准项目布局 myproject/ ├── cmd/ │ └── myapp/ │ └── main.go # 入口点 ├── internal/ │ ├── handler/ # HTTP 处理器 │ ├── service/ # 业务逻辑 │ ├── repository/ # 数据访问 │ └── config/ # 配置 ├── pkg/ │ └── client/ # 公共 API 客户端 ├── api/ │ └── v1/ # API 定义(proto, OpenAPI) ├── testdata/ # 测试夹具 ├── go.mod ├── go.sum └── Makefile 包命名 // Good: Short, lowercase, no underscores package http package json package user // Bad: Verbose, mixed case, or redundant package httpHandler package json_parser package userService // Redundant 'Service' suffix 避免包级状态 // Bad: Global mutable state var db *sql.DB func init () { db, _ = sql.Open( "postgres" , os.Getenv( "DATABASE_URL" )) } // Good: Dependency injection type Server struct { db *sql.DB } func NewServer (db *sql.DB) *Server { return &Server{db: db} } 结构体设计 函数式选项模式 type Server struct { addr string timeout time.Duration logger *log.Logger } type Option func (*Server) func WithTimeout (d time.Duration) Option { return func (s *Server) { s.timeout = d } } func WithLogger (l *log.Logger) Option { return func (s *Server) { s.logger = l } } func NewServer (addr string , opts ...Option) *Server { s := &Server{ addr: addr, timeout: 30 * time.Second, // default logger: log.Default(), // default } for _, opt := range opts { opt(s) } return s } // Usage server := NewServer( ":8080" , WithTimeout( 60 *time.Second), WithLogger(customLogger), ) 使用嵌入实现组合 type Logger struct { prefix string } func (l *Logger) Log(msg string ) { fmt.Printf( "[%s] %s\n" , l.prefix, msg) } type Server struct { *Logger // Embedding - Server gets Log method addr string } func NewServer (addr string ) *Server { return &Server{ Logger: &Logger{prefix: "SERVER" }, addr: addr, } } // Usage s := NewServer( ":8080" ) s.Log( "Starting..." ) // Calls embedded Logger.Log 内存与性能 当大小已知时预分配切片 // Bad: Grows slice multiple times func processItems (items []Item) []Result { var results []Result for _, item := range items { results = append (results, process(item)) } return results } // Good: Single allocation func processItems (items []Item) []Result { results := make ([]Result, 0 , len (items)) for _, item := range items { results = append (results, process(item)) } return results } 为频繁分配使用 sync.Pool var bufferPool = sync.Pool{ New: func () interface {} { return new (bytes.Buffer) }, } func ProcessRequest (data [] byte ) [] byte { buf := bufferPool.Get().(*bytes.Buffer) defer func () { buf.Reset() bufferPool.Put(buf) }() buf.Write(data) // Process... return buf.Bytes() } 避免在循环中进行字符串拼接 // Bad: Creates many string allocations func join (parts [] string ) string { var result string for _, p := range parts { result += p + "," } return result } // Good: Single allocation with strings.Builder func join (parts [] string ) string { var sb strings.Builder for i, p := range parts { if i > 0 { sb.WriteString( "," ) } sb.WriteString(p) } return sb.String() } // Best: Use standard library func join (parts [] string ) string {
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。