golang effective 翻译
参考
Effective Go 官方文档
其他参考译文
https://studygolang.com/articles/3228
http://docscn.studygolang.com/doc/effective_go.html
Intruction
Go是一门新语言。尽管它也借鉴了现存语言的一些思想,使用GO完成一个高效(优秀)的程序,相比使用其他类似语言差异巨大。
直接将C++或Java翻译成Go是写不出好程序的(unlikely to produce a satisfactory result) ----Java程序就要用Java写,不能用Go。
Think about the problem from Go perspective could produce a succcessful but quite different program.
以Go的视角思考程序,会产生与从不同的优秀设计。
换种说法,要想写好Go程序,理解Go的特性和习惯十分重要。
It's also important to know the established conventions for programming in Go,
另外,了解Go程序的构建习惯也很重要,像命名,格式化,组织结构等等,规例这些标准的程序,其他Go开发者才更容易理解。
本文档描述如何编写清晰,符合惯例的Go代码技巧。
It augments the language specification, the Tour of Go, and How to Write Go Code, all of which you should read first.
此读此文档之前,最好先看看 语言规划,Go手册,如何编写Go代码几个文档。
Examples
Go package sources 不仅是核心库代码,也是演示如何Go语言的代码样例。此外,其中许多package是自包含且可执行的示例,
你能直接在 golang.org 网站中运行。
如果你有类似 “如何解决某问题” 或者 “如何实现某功能” 的疑问,也许能在这此文档、代码和示例找到答案或一丝线索。
Formatting
Formatting issues are the most contentious but the least consequential.
代码格式化(排版)也许是争议最多,但最不重要的问题了。
People can adapt to different formatting styles but it's better if they don't have to, and less time is devoted to the topic if every one adheres to the same style.
人们能适应不同的格式化风格,但如果所有人都坚持一种网络,就能在此类争议中节省更多时间
The problem is how to approach this Utopia without a long prescriptive style guide.
问题是,如何能在脱离冗长的代码风格指南的情况下,达到这种理想乌托邦呢。
在Go中,我们用了一种不同寻常的办法,那就是让机器解决大部分格式化问题。 gofmt 程序(即 go fmt命令,which operate at the package level rather than source file level)用于读取Go代码,并将源码缩进、对齐、注释等规范成标准风格。
如果不清楚如何处理某种代码格式,那就运行gofmt;,如果结果不太对,重新整理代码后重试一下(也可以给 gofmt提一个bug)
看看下面的示例,我们不用浪费时间将结构体中的字段名对齐了,直接用 gofmt就能解决。看看下面的声名:
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格式化过。
还剩一些格式化要求,简介如下:
- Indentation 缩进
我们使用 tabs 缩进,gofmt默认也这样。非特殊情况,不要使用空格缩进 - Line length 行长度
Go不限制每行代码的长度。Don't worry overflowing a punched card. 不要担心穿孔卡片宽度不够(最早编程用穿孔卡片)。
如果觉得一行太长了,就换行,然后用几个 tabs 缩进一下就行。 - Parentheses 圆括号
Go相比C和Java很少使用圆括号,控制结构(如 if, for, switch)的语法中都不要求圆括号。
运算符的优先级别也更简洁清晰,比如:
x<<8 + y<<16
表示含义同空格分隔的一样,不像其他语言那么麻烦(TODO验证其他语言有什么问题?)
Commentary 注释
Go提供C风格的块注释/* */,还有C++风格的行注释//。行注释使用更普遍一些,块注释较多用于package注释中,
另外也用于行内注释,或者注释某一大段代码块。(行内注释即: if a>b /&& a>c/ ,其中 a>c的条件就失效了 )
godoc命令用于提取Go源代码中的注释。
Comments that appear before top-level declarations. with no intervening newlines, are extracted along with the declaration to serve as explanatory text for the item. The nature and style of these comments determines the quality of the documentation godoc produces.
每个紧挨 package 声名(clause) 的块注释中,都该有package说明注释(comments)。对于含有多个文件的package,说明应该集中在一个文件中(任意一个文件都可以)。
package的说明应该包含自己简介,及所有相关信息。
这些注释会出现在 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 很简单,package 注释也可以简略一点。
// Package path implements utility routines for
// manipulating slash-separated filename paths.
说明(comments)文字本身不需要格式化(如banners of starts)。godoc输出的文档是非等宽字体,
所以不能像gofmt那样依赖空格对齐。
The comments are uninterpreted plain text, so HTML and other annotations such as this will reproduce verbatim and should not be used. One adjustment godoc does do is to display indented text in a fixed-width font, suitable for program snippets. The package comment for the fmt package uses this to good effect.
说明文字是不经过处理的文本,所以类似 HTML 或者 this 一类的符号会直接显示,尽量不要使用。
但 godoc 会使用等宽字体显示缩进过的文本,用来放置代码片段。标准库中 fmt 就使用了类似效果。
Depending on the context, godoc might not even reformat comments, so make sure they look good straight up: use correct spelling, punctuation, and sentence structure, fold long lines, and so on.
根据实际情况, godoc 也许不会改动说明的格式,一定确保拼写、标点、句子结构以及换行都没有问题。
package内部,所有紧挨声明之上的注释文字,都被当做文档。所有导出变量(大写字母开头)都会生成文档。
Doc comments work best as complete sentences, which allow a wide variety of automated presentations. The first sentence should be a one-sentence summary that starts with the name being declared.
文档说明最好是一个完整句子,这样方便任意显示格式。注释的第一句话,应该以所声名的变量名称开头,做简要介绍。
// 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
如果文档说明没有以它描述的函数名开关(即"Compile"),grep 就没法显示出准确的函数名。
但我们要求每个package中的文档注释都以它描述的变量名开头,你就能看到类似下面的输出结果:
$ 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
$
// TODO 在 windows 7 go 1.9.1 中测试,godoc 输出的函数文档虽然逻辑上是一句话
// 但实际输出仍然是多行的,所以 grep 过滤时,不会显示 Compile 这行字符
// 这也就达不到上文说的目的了,不知道是不是我测试环境有问题?
Go's declaration syntax allows grouping of declarations. A single doc comment can introduce a group of related constants or variables. Since the whole declaration is presented, such a comment can often be perfunctory.
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 ')'")
...
)
批量声名通常指明几个相关数据项,比如下面这种,多个变量同时由一个mutex保护。
var (
countLock sync.Mutex
inputCount uint32
outputCount uint32
errorCount uint32
)
Names
Go语言中命名的重要性同其他语言一样。命名甚至能影响语法:package中变量名称首字母大小写决定其是否对外部可见。
因此值我们花点时间了解有关Go的命名习惯。
Package Names
当 package 导入(import)时,其 package name 就是一个访生问器。出现下面代码后,
import "bytes"
我们就能使用 bytes.Buffer 这样的类型了。每个使用 package 的人都能用相同的 name 引用package,
就说明这是一个具备这些特点的好的名称:短、简洁、形象 (vocative) 。
packages 一般使用小字的单个单词命名,不加下划线或者大小写字母。
Err on the side of brevity, since everyone using your package will be typing that name.
不用担心冲突(collisions a priori)。 package name 只是import时的默认名称;没必要在所有源代码中都是唯一的。
偶尔遇到冲突时,使用局部重命名就能解决。而且import的名称只决定被使用的package。(In any case, confusion is rare because the file name in the import determines just which package is being used.)
另外一个惯例是,package 名称是源代码所有目录的名称;
比如 src/encoding/base64 导入时使用 import "encoding/base64" ,但真正调用时,使用"base64"作为名称。
既不是encoding_base64,也不是encodingBase64。
使用者通过 package name 引用 package 中的内容,so exported names in the package can use that fact to avoid stutter.
(Don't use the import . notation, which can simplify tests that must run outside the package they are testing, but should otherwise be avoided.)
比如在bufio中的 buffered reader 的 package name 是Reader,而不是BufReader,因为使用者通过 bufio.Reader 调用。
因为调用者总会加上 package name 为前缀使用,所以 bufio.Reader 永远不会和 io.Reader 冲突。
同样,一般用于创建一个ring.Ring的新实例的函数,我们起名为NewRing,但因为Ring中 package ring 中的导出类型,
所以我们将函数命名为New就可以了。这样用户就能使用ring.New这种简洁的名称。
利用 package 的目录结构帮你起个好名字。(Use the package structure to help you choose good names.)
还有个例子,once.Do; once.Do(setup)明显就比once.DoOrWaitUntilDone(setup)好多了。
过长的名字反而可能影响可读性。好的 doc comment 可能比冗长的名称要有用得多。
(译:结论我同意,但这个例子中,我觉得 DoOrWaitUntilDone() 更好,还不到20个字符的名字,不能算长
golang effective 翻译的更多相关文章
- Go的50度灰:Golang新开发者要注意的陷阱和常见错误(转)
目录 [−] 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable ...
- [转载]Go的50度灰:Golang新开发者要注意的陷阱和常见错误
初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 偶然的变量隐藏Accidental Variable Shadow ...
- Golang新开发者要注意的陷阱和常见错误
转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 目录 [−] 初级 开大括号不能放在单独的一行 未使 ...
- GO 新开发者要注意的陷阱和常见错误
转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 初级 开大括号不能放在单独的一行 未使用的变量 未使 ...
- Effective Modern C++翻译(1):序言
/*********************************************************** 关于书: 书是我从网上找到的effective Modern C++的样章,内 ...
- 《Effective Modern C++》翻译--简单介绍
北京时间2016年1月9日10:31:06.正式開始翻译.水平有限,各位看官若有觉得不妥之处,请批评指正. 之前已经有人翻译了前几个条目,有些借鉴出处:http://www.cnblogs.com/m ...
- <More Effective C#: 改善C#代码的50个有效方法>中文版翻译答疑
最近, 有一本很赞的.NET技术书中文版出版了 - <More Effective C#: 改善C#代码的50个有效方法>. 从广州\西安\长沙\上海等各地.NET俱乐部都收到反馈, ...
- Golang+Protobuf+PixieJS 开发 Web 多人在线射击游戏(原创翻译)
简介 Superstellar 是一款开源的多人 Web 太空游戏,非常适合入门 Golang 游戏服务器开发. 规则很简单:摧毁移动的物体,不要被其他玩家和小行星杀死.你拥有两种资源 - 生命值(h ...
- 翻译下 golang package time
# 关于 `package time` 个人体会:"wall clock" 可以理解为就是实际的时钟,而 "monotonic clock" 则是程序内部的时钟 ...
随机推荐
- LeetCode567. Permutation in String
Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. I ...
- CCS选择器基础
上周学习了HTML和css的一些基础,今天来夯实一下基础 选择器有: 1.标签选择器 :就是HTML 中的标签 如<p> <h1> <body>等 2.类选择器: ...
- java高并发之CountDownLatch,CyclicBarrier和join
晚上打车回家,在车上看到一篇文章<22岁大学生获谷歌天价Offer,年薪千万!>,讲的是印度一个22岁大学生多次参加ACM大赛,开源多个项目,以非常牛逼的履历通过了谷歌的AI测试,斩获谷歌 ...
- Maven - 依赖范围<scope></scope>
6种:
- Can't connect to local MySQL server through socket '/tmp/mysql.sock'
今天在连接mysql的时候出现了上面的错误, 很明显原因找不到/socket 文件 查了半天才发现原来是mysql没有开启 service mysqld start 开启之后在/tmp/目录下回自 ...
- ArrayList & Vector的源码实现
#ArrayList & Vector #####前言: 本来按照计划,ArrayList和Vector是分开讲的,但是当我阅读了ArrayList和Vector的源码以后,我就改变了注意,把 ...
- spider_main.py
coding=UTF-8 import html_download import html_outputer import html_parser import url_maneger class S ...
- zookeeper: web ui工具的安装
zookeeper官方没有提供web用户界面,这使很多人在使用zookeeper(动物管理员)同时,并不是很容易的理解zookeeper的数据结构,还好淘宝有位大神用Nodejs写了一个web的ui工 ...
- HDU 4576 Robot(概率dp)
Robot Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total Sub ...
- JWT应用
调试器库简介问一件T恤! 精心制作 JSON Web令牌简介 新:免费获得JWT手册并深入学习JWT! 什么是JSON Web Token? JSON Web Token(JWT)是一个开放标准(RF ...