我们必须遵循的 12 个 Go 语言最佳实践

本文旨在提供一个切实的指导,在 Go 语言中实现最佳实践和设计模式。这些编程技巧可以帮助开发者编写出较好的代码。

为了让大家对这些编程技巧有更加深刻的认识,我在讨论这些最佳实践的时候会附加一些示例代码。

那些编写了许多优秀代码的大师们,一直在使用一些 Go 语言编程实践或者说是编程技巧。

下面列出了其中一些最好的编程实践,可以使写出的代码简单、易懂并且易于维护

1、使用 gofmt

2、通过首先处理错误来避免代码嵌套

3、错误字符串

4、错误处理

5、尽量避免代码重复

6、变量名声明

7、用类型选择语句来处理特例

8、在类型选择语句中声明变量

9、重要的代码要放在源文件的前面

10、点导入

11、注释代码

12、注释语句规范

1、使用 gofmt

对源代码执行 gofmt 命令,会自动修正大部分粗心导致的问题。几乎全世界的 Go 语言开发者都在用 gofmt。

gofmt 首先读取源代码,然后输出经过缩进、垂直对齐甚至规范注释后的代码。

命令和选项

gofmt 文件名 - 输出格式化后的代码

gofmt -w 文件名 - 重新格式化代码并更新文件

gofmt -r'rule' 文件名 - 格式化代码前执行指定的规则

gofmt 包所在的路径 - 格式化整个包下的源文件

下面是使用 gofmt 的一些小例子

文件名:demo.go

package main
import "fmt"
// this is demo to format code
// with gofmt command
var a int=10;
var b int=15;
var c string= "Welcome to Agira";
func print(){
fmt.Println("Value for a,b and c is : ");
fmt.Println(a);
fmt.Println((b));
fmt.Println(c);
}
输入命令:$ gofmt demo.go

输出结果:

package main

import "fmt"

// this is demo to format code
// with gofmt command
var a int = 10
var b int = 15
var c string = “Welcome to Agira”

func print() {
fmt.Println("Value for a,b and c is : ")
fmt.Println(a)
fmt.Println((b))
fmt.Println(c)
}
2、通过首先处理错误来避免代码嵌套

避免使用多重条件或者嵌套条件,当我们处理后面的代码前需要处理错误,例如下面的代码

err := request()
if err != nil {
// handling error
} else {
// normal code
}
我们可以用下面的方式代替

err := request()

if err != nil {
// handling error
return // or continue, etc.
}
// proceed to further
嵌套条件语句越少,读者越容易理解

如果 if 语句中包含初始化语句,例如:

if x, err := f(); err != nil {
// handling error
return
} else {
// use x
}
我们应该在代码中定义一个短变量,在之后的 if 语句中使用这个变量

x, err := f()
if err != nil {
// handling error
return
}
// use x
3、错误字符串

错误字符串首字母不应该大写(除非是以一些特殊的名词或者缩写开头)。

例如:

fmt.Errorf("Something went wrong") 应该写成 fmt.Errorf("something went wrong")

4、错误处理

不要用 _ 来忽略错误。如果一个函数可能返回错误信息,检查函数的返回值 ,确认函数是否执行成功了。更好的做法是处理这个错误并返回,不然的话如果出现任何异常程序会产生一个 panic 错误

不要用 panic 错误

不要在正常处理流程中使用 panic, 那种情况下可以用 error 和多重返回值。

5、尽可能避免重复

如果你想在控制模块和数据模块使用同一个类型结构,创建一个公共文件,在那里声明这个类型

6、变量名声明

在 Go 编程中最好用短的变量名,尤其是那些作用域比较有限的局部变量

用 c 而不是 lineCount

用 i 而不是 sliceIndex

1、基本规则:距离声明的地方越远,变量名需要越具可读性。

2、作为一个函数接收者,1、2 个字母的变量比较高效。

3、像循环指示变量和输入流变量,用一个单字母就可以。

4、越不常用的变量和公共变量,需要用更具说明性的名字。

7、用类型选择语句来处理特例

如果你不确定 iterface{} 是什么类型,就可以用类型选择语句

例如:

func Write(v interface{}) {
switch v.(type) {
case string:
s := v.(string)
fmt.Printf(“%T\n”,s)
case int:
i := v.(int)
fmt.Printf(“%T\n”,i)
}
}
8、在类型选择语句中声明变量

在类型选择语句中声明的变量,在每个分支中会自动转化成正确的类型

例如:

func Write(v interface{}) {
switch x := v.(type) {
case string:
fmt.Printf(“%T\n”,x)
case int:
fmt.Printf(“%T\n”,x)
}
}
9、重要的代码要放在源文件的前面

如果你有像版权声明、构建标签、包注释这样的重要信息,尽量写在源文件的靠前位置。 我们可以用空行把导入语句分成若干个组,标准库放在最前面。

import (
"fmt"
"io"
"log"
"golang.org/x/net/websocket"
)
在接下来的代码中,首先写重要的类型,在最后写一些辅助型的函数和类型。

10、点导入

点导入可以测试循环依赖。并且它不会成为被测试代码的一部分:

package foo_test

import (
"bar/testutil" // also imports "foo"
. "foo"
)
这样的情况下,测试代码不能放在 foo 包中,因为它引入了 bar/testutil包,而它导入了 foo。所以我们用点导入 的形式让文件假装是包的一部分,而实际上它并不是。除了这个使用情形外,最好不要用点导入。因为它会让读者阅读代码时更加困难,因为很难确定像 Quux 这样的名字是当前包的顶层声明还是引入的包。

11、注释代码

在包名字之前添加包相关的注释

// Package playground registers an HTTP handler at “/compile” that
// proxies requests to the golang.org playground service.

package playground
出现在 godoc 中的标识符,需要适当的注释

// Author represents the person who wrote and/or is presenting the document.
type Author struct {
Elem []Elem
}

// TextElem returns the first text elements of the author details.
// This is used to display the author’ name, job title, and company
// without the contact details.
func (p *Author) TextElem() (elems []Elem) {
12、注释语句规范

即使注释语句看上去有一些冗余,也需要是一个完整的句子,。这样会让它们在 godoc 中有更的格式化效果。注释需要以被注释的名字开头,以点号结尾。

// Request represents a request to run a command.
type Request struct { …

// Encode writes the JSON encoding of req to w.
func Encode(w io.Writer, req *Request) { … and so on.
希望这些 Go 语言最佳实践可以帮助你提高代码质量。我们也列出了其它许多技术的最佳实践。

via: http://www.agiratech.com/12-best-golang-agile-practices-we-must-follow/

作者:Reddy Sai 译者:jettyhan 校对:polaris1119

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 一、数据类型转换 https://studygolang.com/articles/10838 package m...
    蓓蓓的万能男友阅读 1,071评论 0 1
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 1,095评论 0 3
  • Golang是我最喜欢的一门语言,它简洁、高效、易学习、开发效率高、还可以编译成机器码… 虽然它一出世,就饱受关注...
    盘木阅读 3,548评论 0 7
  • 使用定时器t := time.NewTicker(1 * time.Second)// 第一种方式for { ...
    qishuai阅读 915评论 0 2
  • 安装 官网下载地址:https://golang.org/dl/ ,根据系统平台下载对应资源包,安装或解压到对应目...
    鱼籽灬阅读 712评论 0 0