| name | golang-style |
| description | Use this skill BEFORE writing or editing any Go (.go) files. Triggers when about to create, modify, or add code to .go files. Enforces happy path coding, error wrapping, sentinel errors, and godoc-style comments. |
Go Coding Conventions
Follow these conventions strictly when writing Go code.
Happy Path Coding
Structure code so the successful path flows straight down. Handle errors
immediately, then continue with main logic.
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err != nil {
return nil, fmt.Errorf("get user %s: %w", id, err)
}
if err := user.Validate(); err != nil {
return nil, fmt.Errorf("validate user %s: %w", id, err)
}
return user, nil
}
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err == nil {
if err := user.Validate(); err == nil {
return user, nil
} else {
return nil, err
}
}
return nil, err
}
Error Wrapping
Always wrap errors with context using %w. Include the operation and relevant
identifiers.
if err != nil {
return fmt.Errorf("create order for customer %s: %w", customerID, err)
}
if err != nil {
return err
}
Sentinel Errors
Define package-level sentinel errors for expected error conditions. Use
errors.Is() to check.
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
func GetUser(id string) (*User, error) {
user := db.Find(id)
if user == nil {
return nil, ErrNotFound
}
return user, nil
}
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
}
Comments
All comments end with a period.
func ProcessOrder(o *Order) error {
if err := o.Validate(); err != nil {
return err
}
return nil
}
Naming Conventions
Never use Go's predeclared identifiers as variable or parameter names. These
include built-in functions and constants that can be shadowed but should not be.
func process(new string, len int, make bool) error {
copy := "data"
return nil
}
func process(name string, length int, shouldCreate bool) error {
dataCopy := "data"
return nil
}
Predeclared identifiers to avoid:
- Functions:
new, make, len, cap, append, copy, delete, close,
panic, recover, print, println, complex, real, imag, clear,
min, max
- Constants:
true, false, iota, nil
- Types:
error, bool, string, int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, uintptr, float32,
float64, complex64, complex128, byte, rune, any, comparable
Line Length
Maximum line length is 120 characters. Break long lines at logical points.
func ProcessOrderWithValidation(
ctx context.Context,
order *Order,
validator OrderValidator,
) (*Result, error) {
return nil, fmt.Errorf(
"process order %s for customer %s: %w",
order.ID,
order.CustomerID,
err,
)
}
Documentation Lookup
Use go doc to look up standard library and package documentation:
go doc fmt.Errorf
go doc errors.Is
go doc context
Einride
If the project is under the Einride organization, always use the Makefiles in
the project which are generated by Sage (the .sage folder).