Effictive Go(二)格式与注释

格式

格式问题是最具争议但同时也是最无关紧要的。人们可以使用不同的格式风格,但最好不要这么做。如果人们都坚持同一种风格,就不用在这个话题上花费太多时间了。现在的问题是不通过长效的风格指导,如何达到这个乌托邦。

在Go中我们采取了独特的方式,就是让机器来关心大多数的格式问题。gofmt程序(也可以被称为go fmt,工作在程序包级别而不是源代码级别)读入一个Go程序,并输出具有标准缩进和垂直对齐的程序,保留根据需要重新格式化的注释。如果你想知道如何处理一些新的布局情况,运行gofmt;如果这个答案看起来不太对,重新组织你的程序(或者提交一个gofmt的bug),不要跳过它。

作为一个示例,没有必要花费时间将结构体字段中的注释排列。Gifmt将会为你做这些。给出下列声明:

type T struct {
    name string // name of the object
    value int // its value
}

gofmt将会按列进行排列

type T struct {
    name    string // name of the object
    value   int    // its value
}

所有在标准程序包中的Go代码都已经通过gofmt排列过。
还是有一些排列的细节。非常简短:
缩进:
我们使用tab进行缩进,同时也是gofmt的默认输出。仅在你必要的时候使用空格键。
行长度:
Go没有行长度的限制。不用担心有打孔卡片溢出。如果感觉一行太长了,把它折成几行并用额外的tab缩进。
括号:
相较于C和JAVA,Go更少地使用括号:控制结构(if, for, switch)并没有在它们的语法中使用括号。同时,操作符的优先级更短更清晰,像

x<<8 + y<<16 

的含义以及由空格表明,不像其他语言

注释

Go提供了C风格的/* */块注释和C++风格的//行注释。行注释是规范的;块注释大多出现在程序包的注释中,但是在表达式式中或者注释大量代码行的时候,块注释也是很有用的。

程序——同时又是网络服务器——godoc处理Go源文件来抽取关于包内容的文档。出现在顶层声明之前,并且中间没有换行的注释会随着声明被抽取出来,作为该项的解释性文本。这些注释的本质和风格决定了godoc产生的文档的质量。

每一个包中都有一段包注释,一个位于包子句之前的块注释。对于有多个文件的包,包注释仅仅需要出现在一个文件中,在任何一个文件中都可以。包注释应该介绍包的信息同时提供与整个包相关联的信息。它将首先出现在godoc页面上,并会建立后续的详细文档。

/*
Package regexp implements a simple library for regular expressions.

The syntax of the regular expressions accepted is:

    regexp:
        concatenation { '|' concatenation }
    concatenation:
        { closure }
    closure:
        term [ '*' | '+' | '?' ]
    term:
        '^'
        '$'
        '.'
        character
        '[' [ '^' ] character-ranges ']'
        '(' regexp ')'
*/
package regexp

如果包很简单,包注释也可以很简洁。

// Package path implements utility routines for
// manipulating slash-separated filename paths.

注释不需要额外的格式,例如星条横幅。生成的输出也许不会最为混合宽度的字体展现。所以不要依赖空格来对齐,godoc就像gofmt一样,会帮你处理好这些。注释是不会被解释的纯文本,所以HTML和其他注解,例如_this_将会被逐字复制。godoc会用不同宽度的字体来对缩进的文本进行一些调整,来适应程序片段。fmt包的包注释用了这种方式取得了很好的效果。

根据上下文环境,godoc也许不会重新格式化注释,所以要确保它们看起来够直接:使用正确的拼写,标点,句子结构并折叠长句等。

在一个程序包中,任何在顶层声明之前的注释都会作为该声明的文档注释。每一个在程序中导出(大写)的变量都应该有文档注释。

文档注释最好作为完整的句子实现,这样可以允许各种自动化展示。第一句话应该作为总结句并以声明的变量名开头。

// Compile parses a regular expression and returns, if successful,
// a Regexp that can be used to match against text.
func Compile(str string) (*Regexp, error) {

如果每一个文本注释开始于描述该项的变量名,输出的godoc就可以用grep来处理。假设你正在寻找能解析正则表达式的函数,但是却忘记了”Compile”方法,你可以运行以下命令:

$ godoc regexp | grep -i parse

如果所有在包内的文档注释以”This function…”开头,’grep’将无法帮助你想起这个函数。但是程序包是以变量名来起始每一个文档注释,你将会看到类似这样的信息,这将会使你回想起你在寻找的东西。

$ godoc regexp | grep parse
    Compile parses a regular expression and returns, if successful, a Regexp
    parsed. It simplifies safe initialization of global variables holding
    cannot be parsed. It simplifies safe initialization of global variables
$

Go的声明语法允许组合声明。单个的文档注释可以介绍一组相关联的常量或者变量。因为展示的是整个声明,这样的注释一般都很肤浅。

// Error codes returned by failures to parse an expression.
var (
    ErrInternal      = errors.New("regexp: internal error")
    ErrUnmatchedLpar = errors.New("regexp: unmatched '('")
    ErrUnmatchedRpar = errors.New("regexp: unmatched ')'")
    ...
)

分组还可以用来展示各项之间的关系,分组同样也可以指明项之间的关系,例如实际上是由一个互斥锁所保护的一组变量。

var (
    countLock   sync.Mutex
    inputCount  uint32
    outputCount uint32
    errorCount  uint32
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值