golang-style
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGo Coding Conventions
Go 编码规范
Follow these conventions strictly when writing Go code.
编写Go代码时请严格遵循以下规范。
Happy Path Coding
快乐路径编码
Structure code so the successful path flows straight down. Handle errors
immediately, then continue with main logic.
go
// Correct: happy path flows down.
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
}
// Wrong: main logic nested inside conditions.
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
}代码结构应让成功路径自上而下直线执行。立即处理错误,然后继续主逻辑。
go
// Correct: happy path flows down.
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
}
// Wrong: main logic nested inside conditions.
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 . Include the operation and relevant
identifiers.
%wgo
// Correct: wrapped with context.
if err != nil {
return fmt.Errorf("create order for customer %s: %w", customerID, err)
}
// Wrong: no context.
if err != nil {
return err
}始终使用为错误添加上下文信息,包含操作内容和相关标识符。
%wgo
// Correct: wrapped with context.
if err != nil {
return fmt.Errorf("create order for customer %s: %w", customerID, err)
}
// Wrong: no context.
if err != nil {
return err
}Sentinel Errors
哨兵错误
Define package-level sentinel errors for expected error conditions. Use
to check.
errors.Is()go
// Define at package level.
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
// Return sentinel errors.
func GetUser(id string) (*User, error) {
user := db.Find(id)
if user == nil {
return nil, ErrNotFound
}
return user, nil
}
// Check with errors.Is().
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
// Handle not found case.
}为预期的错误场景定义包级别的哨兵错误,使用进行检查。
errors.Is()go
// Define at package level.
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
// Return sentinel errors.
func GetUser(id string) (*User, error) {
user := db.Find(id)
if user == nil {
return nil, ErrNotFound
}
return user, nil
}
// Check with errors.Is().
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
// Handle not found case.
}Comments
注释规范
All comments end with a period.
go
// ProcessOrder handles order creation and validation.
func ProcessOrder(o *Order) error {
// Validate the order before processing.
if err := o.Validate(); err != nil {
return err
}
// Continue with order processing.
return nil
}所有注释都应以句号结尾。
go
// ProcessOrder handles order creation and validation.
func ProcessOrder(o *Order) error {
// Validate the order before processing.
if err := o.Validate(); err != nil {
return err
}
// Continue with order processing.
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.
go
// Wrong: shadows built-in identifiers.
func process(new string, len int, make bool) error {
copy := "data"
return nil
}
// Correct: use descriptive names instead.
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,minmax - Constants: ,
true,false,iotanil - Types: ,
error,bool,string,int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,uintptr,float32,float64,complex64,complex128,byte,rune,anycomparable
切勿将Go的预声明标识符用作变量或参数名称。这些包括可以被遮蔽但不应被遮蔽的内置函数和常量。
go
// Wrong: shadows built-in identifiers.
func process(new string, len int, make bool) error {
copy := "data"
return nil
}
// Correct: use descriptive names instead.
func process(name string, length int, shouldCreate bool) error {
dataCopy := "data"
return nil
}需避免的预声明标识符:
- 函数:,
new,make,len,cap,append,copy,delete,close,panic,recover,print,println,complex,real,imag,clear,minmax - 常量:,
true,false,iotanil - 类型:,
error,bool,string,int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64,uintptr,float32,float64,complex64,complex128,byte,rune,anycomparable
Line Length
行长度限制
Maximum line length is 120 characters. Break long lines at logical points.
go
// Correct: break 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,
)
}最大行长度为120个字符。在逻辑断点处拆分长行。
go
// Correct: break 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 to look up standard library and package documentation:
go docbash
go doc fmt.Errorf
go doc errors.Is
go doc context使用查询标准库和包的文档:
go docbash
go doc fmt.Errorf
go doc errors.Is
go doc contextEinride
Einride 专属规范
If the project is under the Einride organization, always use the Makefiles in
the project which are generated by Sage (the folder).
.sage如果项目属于Einride组织,请始终使用项目中由Sage(.sage文件夹)生成的Makefile文件。