Comprehensive guidelines for writing idiomatic Go code following community standards, covering naming, error handling, concurrency, testing, and security
Expert guidance for writing clean, idiomatic Go code following community standards from Effective Go, Go Code Review Comments, and Google's Go Style Guide.
This skill provides comprehensive instructions for AI coding assistants when working with Go projects. It ensures code follows idiomatic Go practices, proper naming conventions, effective error handling, safe concurrency patterns, and security best practices.
When writing or reviewing Go code, follow these principles and patterns:
1. **Write simple, clear, and idiomatic Go code**
- Favor clarity and simplicity over cleverness
- Follow the principle of least surprise
- Keep the happy path left-aligned (minimize indentation)
- Return early to reduce nesting
- Make the zero value useful
2. **Documentation**
- Document all exported types, functions, methods, and packages
- Start comments with the name of the thing being described
- Package comments should start with "Package [name]"
- Document why, not what, unless the what is complex
3. **Dependency Management**
- Use Go modules (`go.mod` and `go.sum`)
- Keep dependencies minimal
- Regularly update dependencies for security patches
**Packages:**
**Variables and Functions:**
**Interfaces:**
**Constants:**
**Formatting:**
**Comments:**
**Error Handling:**
```go
// Check errors immediately
result, err := doSomething()
if err != nil {
return fmt.Errorf("failed to do something: %w", err)
}
// Create custom error types when needed
type ValidationError struct {
Field string
Err error
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation failed on %s: %v", e.Field, e.Err)
}
// Use errors.Is and errors.As for checking
if errors.Is(err, ErrNotFound) {
// handle not found
}
```
**Package Organization:**
**Dependency Management:**
**Type Definitions:**
**Pointers vs Values:**
**Interfaces and Composition:**
**Goroutines:**
```go
// Always know how a goroutine will exit
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
for {
select {
case <-ctx.Done():
return
case work := <-workChan:
process(work)
}
}
}()
// Use WaitGroup for coordination
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
doWork()
}()
}
wg.Wait()
```
**Channels:**
**Synchronization:**
**Test Organization:**
```go
// Table-driven tests
func TestParseURL(t *testing.T) {
tests := []struct {
name string
input string
want *URL
wantErr bool
}{
{
name: "valid http url",
input: "http://example.com",
want: &URL{Scheme: "http", Host: "example.com"},
},
{
name: "invalid url",
input: "://invalid",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseURL(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ParseURL() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ParseURL() = %v, want %v", got, tt.want)
}
})
}
}
// Test helpers
func setupTestDB(t *testing.T) *DB {
t.Helper()
db := createDB()
t.Cleanup(func() {
db.Close()
})
return db
}
```
**Input Validation:**
**Cryptography:**
**HTTP Handlers:**
```go
// Simple handler
func handleGet(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
data, err := fetchData()
if err != nil {
http.Error(w, "Internal error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)
}
// Handler with state
type Handler struct {
db *sql.DB
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// implementation
}
```
**Memory Management:**
**Profiling:**
Run these tools regularly:
**Example 1: Create a new HTTP service**
```
Create a RESTful API service with user CRUD endpoints following Go best practices
```
**Example 2: Refactor existing code**
```
Review this Go code and refactor it to be more idiomatic and follow best practices
```
**Example 3: Add concurrency**
```
Make this data processing function concurrent using goroutines and channels safely
```
**Example 4: Write tests**
```
Write table-driven tests for this validation function with good coverage
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/go-development-best-practices-lnij5j/raw