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" 则是程序内部的时钟 ...
随机推荐
- lnmp安装后,phpmyadmin空白
使用lnmp 一键安装后,运行phpinfo是没有问题的,说明php没有问题,但是运行phpmyadmin确实一片空白,网上说的解决方案有几种: 1.config.inc.php增加一个配置$cfg[ ...
- Ansible工作架构和原理
特性 模块块化调用持定的模块,完成持定任务 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块 支持自定义模块 基于Python语法头现 部署简单,基于python和SSH(默认已 ...
- linux学习笔记二:三种网络配置
本文引用自:https://www.linuxidc.com/Linux/2017-05/144370.htm [linux公社] VMware为我们提供了三种网络工作模式,它们分别是:Bridged ...
- 数据分析处理库Pandas——对象操作
Series结构 索引 修改 旧数据赋值给新数据,旧数据不变. 对某一数值进行修改,可以选择保留修改前或修改后的数值. 替换索引 修改某一个索引 添加 在数据1后添加数据2,数据1不改变. 添加一个数 ...
- 两种查看SIP版本的方法python
第一种:进入python命令行 print(sip.SIP_VERSION_STR) 注意对应的PyQt版本号和大小写 print(PyQt5.sip.SIP_VERSION_STR) 第二种:直接在 ...
- 爬取多个url页面数据--手动实现
# -*- coding: utf-8 -*- import scrapy from qiubaiByPages.items import QiubaibypagesItem class Qiubai ...
- ERROR 1005 (HY000): Can't create table 'students.#sql-d9
今天在创建外键的时候出现以下错误 ERROR 1005 (HY000): Can't create table 'students.#sql-d99_3' (errno: 150) 格式 ...
- 匿名函数lambda python
lambda 的主体是一个表达式,不是一个代码块lambda 只有一行,仅仅能在lambda表达式种封装有限的逻辑进去匿名函数:需要一个函数,而又不想动脑筋去想名字 #普通函数的定义 def f(a, ...
- 笔记-爬虫-js代码解析
笔记-爬虫-js代码解析 1. js代码解析 1.1. 前言 在爬取网站时经常会有js生成关键信息,而且js代码是混淆过的. 以瓜子二手车为例,直接请求https://www.guaz ...
- Java学习关于时间操作的应用类--Date类、Calendar类及其子类
Date类 Date类封装了当期时间和日期.与Java1.0定义的原始版的Date类相比,Date类发生了本质的变化.在Java1.1发布时,原始版Date类定义的许多功能被移进Calendar类和D ...