go语言编程系列(二)

简介: go语言编程系列(二)

Golang的命名规范

1、命名在所有的编程语言中都是有规范的,也是需要遵守的,只有我们有了好的命名习惯才可以写出好的代码。例如我们在生活中对建筑的命名也是希望可以表达这个建筑的含义和作用。

2、在Go语言中也是一样的,Go语言的函数名,变量名,常量名,类型名和包的命名都是遵守这一规则的:一个一个名字必须以一个字母或下划线开头,后面可以跟任意数量的字母,数字或者下划线。

3、大写和小写字母是不同的,Car和car是两个不同的名字。

4、Go语言中也有类似java的关键字,且关键字不能自定义名字,只能在特定语法结构中使用。


break default func interface selectcase defer go map structchan else goto package switchconst fallthrough if range typecontinue for import return var

5、除此之外Go语言中还有30多个预定义的名字,比如int和true等


内建常量: true false iota nil内建类型: int int8 int16 int32 int64 uint uint8 uint16 uint32uint64 uintptrfloat32 float64 complex128 complex64 bool byte runestring error内建函数: make len cap new append copy close delete complexreal imag panic recover

6、通常我们在Go语言编程中推荐命名方式是驼峰命名例如:ReadAll,不推荐下划线命名。

7、下面总结了平时项目中必须遵守的规范:

Import规范

①、原则上遵守go imports 规范,go imports会自动把依赖按首字母排序,并对包进行分组管理,通过空行隔开,默认分为本地包(标准库,内部包),第三方包。

②、标准包永远位于最上面的第一组。

③、使用完整路径,不要使用相对路径。

④、包名和git路径不一致时,或者多个相同包名冲突时,使用别名代替。

错误处理

①、error作为函数的值返回,必须对error进行处理,或者返回值赋值给明确忽略。

②、error作为函数值返回且有多个返回值的时候,error必须是最后一个参数。


// 不建议func do() (error, int) {}// 建议func do() (int, error) {}

③、优先处理错误,能return尽早return,理想情况代码逻辑是平铺顺着读就能看得懂,过多的嵌套会降低可读性。

④、错误返回优先独立判断,不与其他变量组合判断


// 不建议x, y, err := f()if err != nil || y == nil {return err // 当y与err都为空时,函数的调用者会出现错误的调用逻辑}// 建议x, y, err := f()if err != nil {return err}if y == nil {return fmt.Errorf("some error")}

panic

①、在业务逻辑处理中禁止使用panic


②、在main包中只有当完全不可运行的情况可使用panic,例如:文件无法打开,数据库无法连接导致程序无法正常运行。

③、对于其他的包,可导出的接口不能有panic,只能在包内使用

④、建议在main包中使用log.Fatal来记录错误,这样就可以由log来结束程序,或者将panic抛出的异常记录到日志文件中,方便排查问题。

⑤、panic捕获只能到goroutine最顶层,每个自行启动的groutine,必须在入口处捕获panic,并打印详细堆栈信息或进行其他处理。

recover

①、recover用于捕获runtime的异常,禁止滥用recover。

②、必须在defer中使用,一般用来捕获程序运行期间发生异常抛出的panic或程序主动抛出的panic。

单元测试

①、单元测试文件名命名规范为example_test.go

②、测试用例的函数名称必须以Test开头,例如TestExample

③、如果存在func Foo,单测函数可以带下划线,为func Test_Foo,如果存在func(b*Bar)Foo,单测函数可以为func TestBar_Foo,下划线不能出现在前面描述情况以外的位置。

④、每个重要的可导出函数都要首先编写测试用例,测试用例和正规代码一起提交方便回归测试。

类型断言失败处理

type assertion的单个返回值形式针对不正确的类型将产生panic。因此,请始终使用"comma ok"的惯用法


var i interface{}// 不建议t := i.(string)

i.(string) 将i或至少尝试将i(type interface{})强制转换为type string。

尝试是因为说i是int,强制转换为type string会panic恐慌。

如果这听起来不太好,则可以将语法更改为


x,ok:=i.(string)

在这种情况下,如果i不是string,则代码ok为false,而代码不会panic恐慌。


// 建议t, ok := i.(string)if !ok {// 优雅地处理错误}

注释:

①、在编码阶段同步写好变量,函数,包注释,注释可以通过godoc导出生成文档。

②、程序中每个被导出(大写的)名字,都应该有一个文档注释

③、所有注释掉的代码在提交code review前都应该被删除掉,除非添加注释讲解为什么删除,并且标明后续处理建议(比如删除计划).

命名规范:

①、文件名应该采用小写,并且使用下划线分割各个单词,文件名尽量采用有意义简短的。

②、结构体,接口,变量,常量,函数均采用驼峰命名。

Golang语言从语法层面进行了以下限定:任何需要对外暴漏的名字必须以大写字母开头,不需要对外暴漏的则以小写字母开头。

当一个命名以一个大写字母开头,如GetUserName,那么使用这种形式的标识符的对象就可以被外部包的代码使用(客户端程序需要先导入这个包),这称为导出(如面向对象语言中的public);命名如果以小写字母开头,则对包外是不可兼得,但是他们在整个包的内部是可见的并且可用的(如面向对象语言中的private)。

举个例子,假设我们有一个包叫做example,其中定义了一个变量"Name":


package examplevar Name string = "hello"

由于变量"Name"的首字母是大写,所以它是可以导出的,可以被其他的包导入后直接使用:


package mainimport (  "fmt"  "example")func main() {  fmt.Println(example.Name) // 输出:hello}

但是如果把"Name"的首字母改为小写,那么它就是不可导出的,外部包是无法访问和使用它:


package example  var name string = "hello"package mainimport (  "fmt"  "example")func main() {  fmt.Println(example.name) // 编译错误:name undefined (cannot refer to  unexported name example.name)}

因此,在Golang中,通过标识符的命名规范则来实现访问控制,可以有效地保障代码的封装性和安全性。

方法命名:

Golang中的方法命名遵循一般的命名规则,遵守首字母大小访问控制规则,同时,也建议采用驼峰命名法。

在Golang中,方法通常是与某个类型(结构体,接口等)关联的函数,方法名应该简洁明了,描述清楚该方法的作用和功能,通常使用动词加上一定的描述或说明来命名。

以下是一些常见的方法命名规范:

①、GetXxx:表示获取某个属性的值,例如GetName:表示获取年龄

②、SetXxx:表示设置某个属性的值,例如SetAge:表示设置年龄

③、AddXxx:表示添加某个元素或者对象,例如AddItem:表示添加一个元素

④、DoXxx:表示执行某个动作,例如DoSomething表示执行某个操作

⑤、XxxWithYyy:表示使用Yyy作为参数执行Xxx操作,例如WriteWithTimout表示使用超时参数执行写操作

需要注意的是,方法名应该尽量使用缩写或缩略语,除非是广泛使用常见的缩写,否则容易引起歧义和误解,同时,方法名应该尽量避免冗长,以保持代码的简洁性和可读性。

例如:假设我们有一个结构体叫做"Person",它有一个方法"SayHello"


type Person struct {   Name string   Age int}func (p *Person) SayHello() {   fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name,   p.Age)}

在上面的例子中,我们使用了驼峰式命名方法来命名方法“SayHello”,同时结合动词和名词来描述该方法的作用,这样做可以使代码更易懂,易读。

变量命名:

和结构体类似,一般遵守驼峰命名法,首字母根据访问控制大小写,但遇到特有名词时,需要遵守以下规则:

如果变量为私有,且特有名词为首个单词,则使用小写,如appService;

若变量为bool类型,则名称应以has,is,can或allow开头。


var isExist boolvar hasConflict boolvar canManage boolvar allowGitHook bool

常量命名:

常量需要使用全部大写字母组成,并使用下划线分词


const APP_URL = "https://www.baidu.com"

如果是枚举类型的常量,需要先创建对应的类型


type Scheme stringconst{   HTTP Scheme = "http"   HTTPS Scheme = "https"}

控制语句

①、if语句


// 不建议,变量优先在左if nil != err {}// 建议这种if err != nil {}// 不建议,bool类型变量直接进行if has == true {}// 建议if has {}

①、switch语句,必须要有default哪怕什么都不做

②、业务代码禁止使用goto,其他框架或底层源码推荐尽量不用。

Defer

①、当存在资源管理时,应紧跟defer函数进行资源的释放

②、判断是否有错误发生之后,再defer释放资源


resp, err := http.Get(url)if err != nil {return err}// defer 放到错误处理之后,不然可能导致panicdefer resp.Body.Close()

③、禁止在循环中的延迟函数中使用defer,因为defer的执行需要外层函数的结束后才会释放,未来会有很多坑


// 不要这样使用func filterSomething(values []string) {  for _, v := range values {  fields, err := db.Query(xxx)  if err != nil {}defer fields.Close()// xxx }}// 但是可以使用这种方式func filterSomething(values []string) {  for _, v := range values {  func() {  fields, err := db.Query(xxx)  if err != nil {  // xxx  }defer fields.Close()  //x xxx  }() }}

魔法数字:

如果魔法数字出现超过2次,则禁止使用


func getArea(r float64) float64 {  return 3.14 * r * r}func getLength(r float64) float64 {  return 3.14 * 2 * r}// 建议定义一个常量代替魔法数字// PI xxxconst PI = 3.14

代码规范性常用工具:

上面提到的很多规范,go语言本身在代码规范性这方面做了很多的努力,很多限制都是强制性语法要求,例如左大括号不换行,引用的包或者定义的变量不使用会报错,此外go还是提供了很多好用的工具帮助我们进行代码规范:

①、gofmt

大部分的格式问题可以通过gofmt解决,gofmt自动格式化代码,保证所有的go代码与官方推荐的格式保持一致,于是所有格式有关的问题,都以gofmt的结果为准。

②、goimport

我们强烈建议使用goimport,该工具在gofmt的基础上增加了自动删除和引入包


go get golang.org/x/tools/cmd/goimports

③、go vet

vet工具可以帮助我们静态分析我们的源码存在的各种问题,例如多余的代码,提前return的逻辑,struct的tag是否符合标准等


go get golang.org/x/tools/cmd/vet
目录
打赏
0
2
2
0
55
分享
相关文章
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
95 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
2月前
|
go语言中数组和切片
go语言中数组和切片
48 7
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
4天前
|
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
52 20
探秘员工泄密行为防线:基于Go语言的布隆过滤器算法解析
在信息爆炸时代,员工泄密行为对企业构成重大威胁。本文聚焦布隆过滤器(Bloom Filter)这一高效数据结构,结合Go语言实现算法,帮助企业识别和预防泄密风险。通过构建正常操作“指纹库”,实时监测员工操作,快速筛查可疑行为。示例代码展示了如何利用布隆过滤器检测异常操作,并提出优化建议,如调整参数、结合日志分析系统等,全方位筑牢企业信息安全防线,守护核心竞争力。
|
10天前
|
Go语言入门:分支结构
本文介绍了Go语言中的条件语句,包括`if...else`、`if...else if`和`switch`结构,并通过多个练习详细解释了它们的用法。`if...else`用于简单的条件判断;`if...else if`处理多条件分支;`switch`则适用于基于不同值的选择逻辑。特别地,文章还介绍了`fallthrough`关键字,用于优化重复代码。通过实例如判断年龄、奇偶数、公交乘车及成绩等级等,帮助读者更好地理解和应用这些结构。
34 14
|
2月前
|
go语言中结构体(Struct)
go语言中结构体(Struct)
124 71
|
2月前
|
go语言中的数组(Array)
go语言中的数组(Array)
121 67
|
25天前
|
内网监控系统之 Go 语言布隆过滤器算法深度剖析
在数字化时代,内网监控系统对企业和组织的信息安全至关重要。布隆过滤器(Bloom Filter)作为一种高效的数据结构,能够快速判断元素是否存在于集合中,适用于内网监控中的恶意IP和违规域名筛选。本文介绍其原理、优势及Go语言实现,提升系统性能与响应速度,保障信息安全。
28 5
Go语言中的加密和解密是如何实现的?
Go语言通过标准库中的`crypto`包提供丰富的加密和解密功能,包括对称加密(如AES)、非对称加密(如RSA、ECDSA)及散列函数(如SHA256)。`encoding/base64`包则用于Base64编码与解码。开发者可根据需求选择合适的算法和密钥,使用这些包进行加密操作。示例代码展示了如何使用`crypto/aes`包实现对称加密。加密和解密操作涉及敏感数据处理,需格外注意安全性。
47 14
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等