第7条 使用Go命名惯例对标识符进行命名
计算机科学中只有两件难事:缓存失效和命名。
——Phil Karlton,Netscape架构师
Go语言的贡献者和布道师Dave Cheney给出了一个说法:“一个好笑话,如果你必须解释它,那就不好笑了。好的命名也类似。”
简单且一致;利用上下文辅助命名。
7.1 简单且一致
Go命名惯例选择了简洁命名+注释辅助解释的方式,而不是一个长长的名字。
和代码整洁之道相反
Go语言建议,包名应尽量与包导入路径(import path)的最后一个路径分段保持一致。
但在实际情况中,包名与导入路径最后分段不同的也有很多。比如:实时分布式消息队列NSQ的官方客户端包的导入路径为github.com/nsqio/go-nsq,但是该路径下面的包名却是nsq。
此外,我们在给包命名的时候,不仅要考虑包自身的名字,还要兼顾该包导出的标识符(如变量、常量、类型、函数等)的命名。由于对这些包导出标识符的引用必须以包名为前缀,因此对包导出标识符命名时,在名字中不要再包含包名,比如:
在Go中变量分为包级别的变量和局部变量(函数或方法内的变量)。
Go语言官方要求标识符命名采用驼峰命名法(CamelCase)
不过如果缩略词的首字母是大写的,那么其他字母也要保持全部大写,比如HTTP(Hypertext Transfer Protocol)
缩略词首字母小写的,其他字母也要小写。
一般来说,Go标识符仍以单个单词作为命名首选。从Go标准库代码的不完全统计结果来看,不同类别标识符的命名呈现出以下特征:
• 循环和条件变量多采用单个字母命名(具体见上面的统计数据);
• 函数/方法的参数和返回值变量以单个单词或单个字母为主;
• 由于方法在调用时会绑定类型信息,因此方法的命名以单个单词为主;
• 函数多以多单词的复合词进行命名;
• 类型多以多单词的复合词进行命名。
(1)变量名字中不要带有类型信息
和代码整洁之道一样
保持变量声明与使用之间的距离越近越好,或者在第一次使用变量之前声明该变量。
有人可能会认为简短命名变量会降低代码的可读性。Go语言建议通过保持一致性来维持可读性。一致意味着代码中相同或相似的命名所传达的含义是相同或相似的,这样便于代码阅读者或维护者猜测出变量的用途。
刚java转go时是有些不习惯,慢慢的就理解其中的好处了。其实就是约定俗成应用到命名中。
变量t的常用含义:
变量b的常用含义:
但在Go语言中,常量在命名方式上与变量并无较大差别,并不要求全部大写。只是考虑其含义的准确传递,常量多使用多单词组合的方式命名。下面是标准库中的例子:
在Go语言中,对于接口类型优先以单个单词命名。对于拥有唯一方法(method)或通过多个拥有唯一方法的接口组合而成的接口,Go语言的惯例是用“方法名+er”命名。比如:
不是所有接口都是用于er结尾
Go语言推荐尽量定义小接口,并通过接口组合的方式构建程序。
7.2 利用上下文环境,让最短的名字携带足够多的信息
Go在给标识符命名时还有着考虑上下文环境的惯例,即在不影响可读性的前提下,兼顾一致性原则,尽可能地用短小的名字命名标识符。这与其他一些主流语言在命名上的建议有所不同,比如Java建议遵循“见名知义”的命名原则。
Go语言追求简单一致且利用上下文辅助名字信息传达的命名惯例,如果你刚从其他语言转向Go,这可能会让你感到不适应,但这就是Go语言文化的一部分,也许等你编写的Go代码达到一定的量,你就能理解这种命名惯例的好处了。
转go一段时间,发现确实如此
第三部分 声明、类型、语句与控制结构
第8条 使用一致的变量声明形式
Gopher在变量声明形式的选择上应尽量保持项目范围内一致。
8.1 包级变量的声明形式
显式为包级变量a和f指定类型,那么有以下两种声明方式:
// 第一种 var a int32 = 17 var f float32 = 3.14// 第二种 var a = int32(17) var f = float32(3.14)
从声明一致性的角度出发,Go语言官方更推荐后者,这样就统一了接受默认类型和显式指定类型两种声明形式。
默认类型就是类型推断出来的
一般将同一类的变量声明放在一个var块中,将不同类的声明放在不同的var块中;或者将延迟初始化的变量声明放在一个var块,而将声明并显式初始化的变量放在另一个var块中。笔者称之为“声明聚类”。
使用静态编程语言的开发人员都知道,变量声明最佳实践中还有一条:就近原则,即尽可能在靠近第一次使用变量的位置声明该变量。就近原则实际上是变量的作用域最小化的一种实现手段。
如果一个包级变量在包内部被多处使用,那么这个变量还是放在源文件头部声明比较适合。
8.2 局部变量的声明形式
要想做好代码中变量声明的一致性,需要明确要声明的变量是包级变量还是局部变量、是否要延迟初始化、是否接受默认类型、是否为分支控制变量,并结合聚类和就近原则。
包级别,用var,局部变量用:(语法糖),延迟赋值声明类型
第9条 使用无类型常量简化代码
9.3 无类型常量消除烦恼,简化代码
Go的无类型常量恰恰就拥有像字面值这样的特性,该特性使得无类型常量在参与变量赋值和计算过程时无须显式类型转换,从而达到简化代码的目的
这里说的变量赋值里的变量类型是指自定义类型,或者类型别名
所有常量表达式的求值计算都可以在编译期而不是在运行期完成,这样既可以减少运行时的工作,也能方便编译器进行编译优化。当操作数是常量时,在编译时也能发现一些运行时的错误,例如整数除零、字符串索引越界等。