最近在项目中也 codereview 了不少 Go 语言的代码,有必要总结下代码规范,算是一个笔记记录了。
说在前面,这只是我们团队的一套规范而已。
今天我们聊一下 Go 的编码规范,大概分为几大模块,如注包/变量/常量命名、基本语法、函数、错误处理、心得等。【推荐:golang教程】
1. 代码风格
1.1 代码格式
- 代码必须用 gofmt 进行格式化,goland 可以配置,可以自行搜索一下配置
- 我们编写的代码每行应该不超过 120 个字符,超出部分用换行解决。
- 单个文件最大行数最大不超过 800 行.
- 单个函数最大行数不超过 80 行。
- import 规范
- 不要使用相对路径引入包,例如
import ../util/net
- 在导入包时,多个相同包名冲突时,必须使用导入别名
- 不要使用相对路径引入包,例如
// 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 声明。在函数外部声明的变量不能使用 :=,会踩坑,不知道的可以评论区留言(要评论不易呀)!
var ( port = 8081 metricServerPort = 2001)
- 在初始化结构体用 &struct 代替 new(struct),确保与结构体初始化一致,初始化结构体时换行。
// bad stu := new(S) stu.Name = "张三" // good stu := &S{ Name:"李四" }
- 使用 make 在声明 map、array 等应该指定容器的容量,从而达到预先分配内容。
users := make(map[int]string, 10)tags := make([]int, 0, 10)
- 使用标准 var 关键字事,不要指定类型,除非它与表达式的类型不同。
// bad var _f string F() func F() string { return "hello world!" } // good var _f F() func F() string { return "hello world!" }
1.3 error 处理
- 若函数返回 error, 必须对 error 进行处理,如果业务允许可以用 _ 接受忽略。对应 defer 可以不用显式进行处理。
// bad func InitConfig() error { ... } InitConfig() // good func InitConfig() error { ... } err := InitConfig() if err != nil { ... } // or _ := InitConfig()
- error 作为返回值时必须作为最后一个参数返回
// 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处理
- 业务代码中禁止抛出 panic 错误。
- panic 只允许出现在在服务启动之前,如读取配置、链接存储(redis、mysql 等)。
- 业务代码中建议用 error 而不是 panic 来传递。
1.5 单元测试
- 每个重要的函数都要编写测试用例,合并代码要自动化运行一下所有的 test。
- 文件命名 xxx_test.go。
- 函数命名建议使用 Test函数名。
2. 命名规范
在每个语言中,命名规范在代码规范中非常重要,一个统一的、精确的命名不仅仅可以提高代码的可读性,也可以让人觉的这个同志真的会呀。牛!
2.1 包命名规范
- 包名必须与目录名一致(这和其他 php、Java 还是有一点不太一样的),尽量采取有意义、简短的包名,不要与 go 的标准库名称一样。
- 包名小写,没有下划线,可以使用中划线隔开,使用多级目录来划分目录。
- 包名不要出现复数命名。
- 包名命名尽量简单一目了然,ge:user、log。
2.2 文件命名规范
- 文件名要见名思义,尽量简而短
- 文件名小写,组合词用下划线分割
2.3 函数命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 单元测试的函数用大驼峰,TestFunc。
2.4 结构体命名规范
- 与 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 避免使用 info 、data 这种无意义的名称。
- 命名使用名词而非动词。
- 结构体在声明和初始化的时候需要换行,eg:
type Student struct{ Name string Age uint8}student := Student{ Name: "张三", Age: 18,}
2.5 变量命名规范
- 和 php、Java 一样,必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若变量为私有时,可以使用小写命名。
- 局部变量可以简写,eg:i 表示 index。
- 若变量代表 bool 值,则可以使用 Is 、Can、Has 前缀命名,eg:
var isExit boolvar canReturn bool
2.6 常量命名规范
- 必须遵循驼峰规范,Go 语言中需要根据访问的控制决定大驼峰还是小驼峰。
- 若代表枚举值,需要先创建。
type Code intconst ( 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 stringif strings.HasPrefix(s1, s2){ s3 = s1[len(s2):]}
3.2 切片 slice
- 声明 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 { ...}
- slice copy。
// badvar b1,b2 []bytefor i, v := range b1 { b2[i] = v}for i := range b1 { b2[i] = b1[i]}// goodcopy(b2,b1)
- slice 新增。
// bad var a,b []intfor _, 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 可以用局部变量的方式初始化。
if err := InitConfig; err != nil { return err}
4.2 for
- 不允许在 for 中使用 defer, defer 只在函数结束时才会执行。
// 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
- 如果不需要 key 直接用 _ 忽略,value 也一样。
for _, v := range students { ...}for i, _ := range students { ...}for i, v := range students { ...}
注: 若操作指针时请注意不能直接用 s := v。想知道可以评论区告诉我哦!
4.4 switch
- 和其他语言不一样,必须要有 defalt
switch type { case 1: fmt.Println("type = 1") break case 2: fmt.Println("type = 2") break default : fmt.Println("unKnown type")}
4.5 goto
- 业务中不允许使用 goto。
- 框架和公共工具也不允许使用 goto。
5. 函数
- 传参和返回的变量小写字母。
- 传入参数时slice、map、interface、chan 禁止传递指针类型。
- 采用值传递,不用指针传值。
- 入参个数不能超出 5 个,超过的可以用 struct 传值。
5.1 函数参数
- 返回值超出 1 个时,需要用变量名返回。
- 多个返回值可以用 struct 传。
5.2 defer
- 当操作资源、或者事物需要提交回滚时,可以在创建开始下方就使用 defer 释放资源。
- 创建资源后判断 error,非 error 情况后在用 defer 释放。
5.3 代码嵌套
- 为了代码可读性,为了世界和平,尽量别用太多的嵌套,因为真的很难有人类能看懂。
6. 日常使用感悟
- 能不用全局变量就不用,可以用参数传值的方式,这样可以大大降低耦合,更有利于单元测试。
- 衣服开发中,在函数间多用 context 传递上下文,在请求开始时可以生成一个 request_id,便于链路、日志追踪。
6.1 提高性能
- 在业务开发中,尽量使用 strconv 来替代 fmt。
- 我们在使用 string 字符串类型时,当修改的场景较多,尽量在使用时用 []byte 来替代。因为每次对 string 的修改都需要重新在申请内存。
6.2 避免踩坑
- append 要小心自动扩容的情况,最好在申明时分配好容量,避免扩容所带来的性能上的损耗以及分配新的内存地址。若不能确定容量,应选择一个比较大一点的值。
- 并发场景下,map 非线程安全,需要加锁。还有一种评论区告诉我吧。
- interface 在编译期间无法被检查,使用上会出现 panic,需要注意
7. 总结
本篇很讲了 Go 语言的编码规范,当时想说的,规范是大家预定的东西,每个公司、团队都会有不一样的规范,只要大家一起遵循就好啦。你可以根据自己团队的需求,定一套属于自己团队的项目规范。如果想小伙伴一起遵循,可以借助一些工具来保障执行度。
讲了很多,虽然很基础,希望对于刚刚转 Go 语言,或者刚学习 Go 语言的同学有帮助吧。今天就到这里了。希望得到大家的一键三连。感谢!
本文系转载,原文链接:mp.weixin.qq.com/s/lfjP9DEia2WL4Ua...
以上是分享一套Go编码规范!欢迎收藏!的详细内容。更多信息请关注PHP中文网其他相关文章!

GoimpactsdevelopmentPositationalityThroughSpeed,效率和模拟性。1)速度:gocompilesquicklyandrunseff,ifealforlargeprojects.2)效率:效率:ITScomprehenSevestAndArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增强开发的简单性:3)SimpleflovelmentIcties:3)简单性。

C 更适合需要直接控制硬件资源和高性能优化的场景,而Golang更适合需要快速开发和高并发处理的场景。1.C 的优势在于其接近硬件的特性和高度的优化能力,适合游戏开发等高性能需求。2.Golang的优势在于其简洁的语法和天然的并发支持,适合高并发服务开发。

Golang在实际应用中表现出色,以简洁、高效和并发性着称。 1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Go语言的核心特性包括垃圾回收、静态链接和并发支持。1.Go语言的并发模型通过goroutine和channel实现高效并发编程。2.接口和多态性通过实现接口方法,使得不同类型可以统一处理。3.基本用法展示了函数定义和调用的高效性。4.高级用法中,切片提供了动态调整大小的强大功能。5.常见错误如竞态条件可以通过gotest-race检测并解决。6.性能优化通过sync.Pool重用对象,减少垃圾回收压力。

Go语言在构建高效且可扩展的系统中表现出色,其优势包括:1.高性能:编译成机器码,运行速度快;2.并发编程:通过goroutines和channels简化多任务处理;3.简洁性:语法简洁,降低学习和维护成本;4.跨平台:支持跨平台编译,方便部署。

关于SQL查询结果排序的疑惑学习SQL的过程中,常常会遇到一些令人困惑的问题。最近,笔者在阅读《MICK-SQL基础�...

golang ...


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

记事本++7.3.1
好用且免费的代码编辑器