Golang语言社区

送给学Go或者转Go同学的一套编码规范

2022-12-13  本文已影响0人  程序员祝融

有没有 xdm 是从别的语言转 Go 的,比如 Java 、php 等,有兄弟在刚开始学的时候疑惑怎么能写出来优秀的代码。最近在项目中也 codereview 了不少 Go 语言的代码,有必要总结下代码规范,算是一个笔记记录了。

说在前面,这只是我们团队的一套规范而已。

今天我们聊一下 Go 的编码规范,大概分为几大模块,如注包/变量/常量命名、基本语法、函数、错误处理、心得等。

1. 代码风格

1.1 代码格式

// bad
"github.com/google/uuid"

// good
uuid "github.com/google/uuid"
import (
    // Go 标准库
    "fmt"

    //第三方包
    "github.com/jinzhu/gorm"
    "github.com/google/uuid"
    "github.com/go-redis/redis/v8"

    // 匿名包
    /import mysql driver
    _"github.com/jinzhu/gorm/dialects/mysql"

    // 内部包
    slice "xxx.local/pkg/v1/goslice"
    meta "xxx.local/pkg/v1/meta"
    gomap "xxx.local/pkg/v2/gomap"
)

1.2 声明、初始化和定义

var (
    port = 8081
    metricServerPort = 2001
)
// bad
stu := new(S)
stu.Name = "张三"

// good
stu := &S{
    Name:"李四"
}
users := make(map[int]string, 10)

tags := make([]int, 0, 10)
// bad
var _f string F()

func F() string {
    return "hello world!"
}

// good 
var _f F()

func F() string {
    return "hello world!"
}

1.3 error 处理

// bad
func InitConfig() error {
    ...
}
InitConfig()


// good
func InitConfig() error {
    ...
}
err := InitConfig()
if err != nil {
    ...
}
// or 
_ := InitConfig() 
// bad
func InitConfig() (error,int) {
    ...
}

// good 
func InitConfig() (int, error) {
    ...
}
// bad
res, err := InitConfig()
if err != nil || res != nil {
    return err
}

// good
res, err := InitConfig()
if err != nil {
    return err
}
if res != nil {
    return fmt.Errorf("invalid result")
}

1.4 panic处理

1.5 单元测试

2. 命名规范

在每个语言中,命名规范在代码规范中非常重要,一个统一的、精确的命名不仅仅可以提高代码的可读性,也可以让人觉的这个同志真的会呀。牛!

2.1 包命名规范

2.2 文件命名规范

2.3 函数命名规范

2.4 结构体命名规范

type Student struct{
    Name string
    Age uint8
}

student := Student{
    Name: "张三",
    Age: 18,
}

2.5 变量命名规范

var isExit bool
var canReturn bool

2.6 常量命名规范

type Code int

const (
    ErrNotFound Code = iota
    ErrFatal
)

3. 类型

3.1 字符串

好像学过的语言中,都是从字符串开始说起的。就像写代码第一行都是从 Hello World!一样!同意的点赞哈。

// bad
if s == "" {
    ...
}

// good
if len(s) == 0 {
    ...
}
// bad
var s1 "hello world"
var s2 "hello"
var s3 strings.TrimPrefix(s1, s2)

// good
var s1 "hello world"
var s2 "hello"
var s3 string

if strings.HasPrefix(s1, s2){
    s3 = s1[len(s2):]
}

3.2 切片 slice

// bad
s := []string{}
s := make([]string, 10)

// good
var s []string
s := make([]string, 0, 10)
//bad
if len(slice) >0 {
    ...
}

// good
if slice != nil && len(slice) > 0 {
    ...
}
// bad
var b1,b2 []byte
for i, v := range b1 {
    b2[i] = v
}
for i := range b1 {
    b2[i] = b1[i]
}

// good
copy(b2,b1)
// bad
var a,b []int
for _, v := range a {
    b = append(b,v)
}

// good
var a, b []int
b := append(b, a...)

3.4 结构体 struct

type Student struct{
    Name string
    Age uint8
}

student := Student{
    Name: "张三",
    Age: 18,
}

4. 控制语句

4.1 if

if err := InitConfig; err != nil {
    return err
}

4.2 for

// bad
for file := range files {
    fd, err := os.Open(file)
    if err != nil {
        return err
    }
    defer fd.close()
    
}

// good
for file := range files{
    func() {
        fd,err := os.open(file)
        if err!=nil {
            return err
        }
        defer fd.close()
    }()
}

4.3 range

for _, v := range students {
    ...
}

for i, _ := range students {
    ...
}

for i, v := range students {
    ...
}

注: 若操作指针时请注意不能直接用 s := v。想知道可以评论区告诉我哦!

4.4 switch

switch type {
    case 1:
        fmt.Println("type = 1")
        break
     case 2:
        fmt.Println("type = 2")
        break
     default :
        fmt.Println("unKnown type")
}

4.5 goto

5. 函数

5.1 函数参数

5.2 defer

5.3 代码嵌套

6. 日常使用感悟

6.1 提高性能

6.2 避免踩坑

7. 总结

本篇很讲了 Go 语言的编码规范,当时想说的,规范是大家预定的东西,每个公司、团队都会有不一样的规范,只要大家一起遵循就好啦。你可以根据自己团队的需求,定一套属于自己团队的项目规范。如果想小伙伴一起遵循,可以借助一些工具来保障执行度。

讲了很多,虽然很基础,希望对于刚刚转 Go 语言,或者刚学习 Go 语言的同学有帮助吧。今天就到这里了。希望得到大家的一键三连。感谢!

欢迎关注微信公众号【程序员祝融】,原文链接:
https://mp.weixin.qq.com/s/lfjP9DEia2WL4UabxsDq0w

上一篇下一篇

猜你喜欢

热点阅读