如何写出优雅的 Golang 代码
Go 语言是一门简单、易学的编程语言,对于有编程背景的工程师来说,学习 Go 语言并写出能够运行的代码并不是一件困难的事情,对于之前有过其他语言经验的开发者来说,写什么语言都像自己学过的语言其实是有问题的,想要真正融入生态写出优雅的代码就一定要花一些时间和精力了解语言背后的设计哲学和最佳实践。

如果你之前没有 Go 语言的开发经历,正在学习和使用 Go 语言,相信这篇文章能够帮助你更快地写出优雅的 Go 语言代码;在这篇文章中,我们并不会给一个长长地列表介绍变量、方法和结构体应该怎么命名,这些 Go 语言的代码规范可以在 Go Code Review Comments 中找到,它们非常重要但并不是这篇文章想要介绍的重点,我们将从代码结构、最佳实践以及单元测试几个不同的方面介绍如何写出优雅的 Go 语言代码。
写在前面
想要写出好的代码并不是一件容易的事情,它需要我们不断地对现有的代码进行反思 — 如何改写这段代码才能让它变得更加优雅。优雅听起来是一个非常感性、难以量化的结果,然而这却是好的代码能够带来的最直观感受,它可能隐式地包含了以下特性:
- 容易阅读和理解;
- 容易测试、维护和扩展;
- 命名清晰、无歧义、注释完善清楚;
- …
相信读完了这篇文章,我们也不能立刻写出优雅的 Go 语言代码,但是如果我们遵循这里介绍几个的容易操作并且切实可行的方法,就帮助我们走出第一步,作者写这篇文章有以下的几个目的:
- 帮助 Go 语言的开发者了解生态中的规范与工具,写出更优雅的代码;
- 为代码和项目的管理提供被社区广泛认同的规则、共识以及最佳实践;
代码规范
代码规范其实是一个老生常态的问题,我们也不能免俗还是要简单介绍一下相关的内容,Go 语言比较常见并且使用广泛的代码规范就是官方提供的 Go Code Review Comments,无论你是短期还是长期使用 Go 语言编程,都应该至少完整地阅读一遍这个官方的代码规范指南,它既是我们在写代码时应该遵守的规则,也是在代码审查时需要注意的规范。
学习 Go 语言相关的代码规范是一件非常重要的事情,也是让我们的项目遵循统一规范的第一步,虽然阅读代码规范相关的文档非常重要,但是在实际操作时我们并不能靠工程师自觉地遵守以及经常被当做形式的代码审查,而是需要借助工具来辅助执行。
辅助工具
使用自动化的工具保证项目遵守一些最基本的代码规范是非常容易操作和有效的事情,相比之下人肉审查代码的方式更加容易出错,也会出现一些违反规则和约定的特例,维护代码规范的最好方式就是『尽量自动化一切能够自动化的步骤,让工程师审查真正重要的逻辑和设计』。
我们在这一节中就会介绍两种非常切实有效的办法帮助我们在项目中自动化地进行一些代码规范检查和静态检查保证项目的质量。
goimports
goimports 是 Go 语言官方提供的工具,它能够为我们自动格式化 Go 语言代码并对所有引入的包进行管理,包括自动增删依赖的包引用、将依赖包按字母序排序并分类。相信很多人使用的 IDE 都会将另一个官方提供的工具 gofmt 对代码进行格式化,而 goimports 就是等于 gofmt 加上依赖包管理。

建议所有 Go 语言的开发者都在开发时使用 goimports,虽然 goimports 有时会引入错误的包,但是与带来的好处相比,这些偶尔出现的错误在作者看来也是可以接受的;当然,不想使用 goimports 的开发者也一定要在 IDE 或者编辑器中开启自动地 gofmt(保存时自动格式化)。
在 IDE 和 CI 检查中开启自动地
gofmt或者goimports检查是没有、也不应该有讨论的必要的,这就是一件使用和开发 Go 语言必须要做的事情。
golint
另一个比较常用的静态检查工具就是 golint 了,作为官方提供的工具,它在可定制化上有着非常差的支持,我们只能通过如下所示的方式运行 golint 对我们的项目进行检查:
$ golint ./pkg/...
pkg/liquidity/liquidity_pool.go:18:2: exported var ErrOrderBookNotFound should have comment or be unexported
pkg/liquidity/liquidity_pool.go:23:6: exported type LiquidityPool should have comment or be unexported
pkg/liquidity/liquidity_pool.go:23:6: type name will be used as liquidity.LiquidityPool by other packages, and that stutters; consider calling this Pool
pkg/liquidity/liquidity_pool.go:31:1: exported function NewLiquidityPool should have comment or be unexported
...
社区上有关于 golint 定制化的 讨论,golint 的开发者给出了以下的几个观点解释为什么 golint 不支持定制化的功能:
lint的目的就是在 Go 语言社区中鼓励统一、一致的编程风格,某些开发者也许不会同意其中的某些规范,但是使用统一的风格对于 Go 语言社区有比较强的好处,而能够开关指定规则的功能会导致golint不能够有效地完成这个工作;- 有一些静态检查的规则会导致一些错误的警告,这些情况确实非常让人头疼,但是我会选择支持在 golint 中直接保留或者删除这些规则,而不是提供随意增删规则的能力;
- 能够通过
min_confidence过滤一些静态检查规则,但是需要我们选择合适的值;
golint 作者的观点在 issue 中得到了非常多的
如何写出优雅的 Golang 代码的更多相关文章
- 如何写出优雅的CSS代码 ?(转)
对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于团队合作和后期的维护:而有的混 ...
- 如何写出优雅的css代码 ?
如何写出优雅的css代码 ? 对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于 ...
- 如何写出优雅的JavaScript代码 ? && 注释
如何写出优雅的JavaScript代码 ? 之前总结过一篇<如何写出优雅的css代码?>, 但是前一段时间发现自己的js代码写的真的很任性,没有任何的优雅可言,于是这里总结以下写js时应当 ...
- 【原创】怎样才能写出优雅的 Java 代码?这篇文章告诉你答案!
本文已经收录自 JavaGuide (59k+ Star):[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识. 本文比较简短,基本就是推荐一些对于写好代码非常有用的文章或者 ...
- 深入了解Promise对象,写出优雅的回调代码,告别回调地狱
深入浅出了解Promise 引言 正文 一.Promise简介 二.Promise的三种状态 三.函数then( ) 四.函数catch( ) 五.函数finally( ) 六.函数all( ) 七. ...
- 如何写出优雅的Python代码?
有时候你会看到很Cool的Python代码,你惊讶于它的简洁,它的优雅,你不由自主地赞叹:竟然还能这样写.其实,这些优雅的代码都要归功于Python的特性,只要你能掌握这些Pythonic的技巧,你一 ...
- 如何写出优雅兼备可读性的javascript代码
即或是最简单的需求,不同的程序员也会写出不一样的代码: 需求:充值程序过虑不符合条件的充值金额,即只能充入100.200.500.1000金额,其它过虑: 1.菜鸟程序员可能会这样写,虽然可读性强,代 ...
- 如何用java写出无副作用的代码
搞java的同学们可能对无副作用这个概念比较陌生,这是函数式编程中的一个概念,无副作用的意思就是: 一个函数(java里是方法)的多次调用中,只要输入参数的值相同,输出结果的值也必然相同,并且在这个函 ...
- fir.im Weekly - 如何写出零 bug 的代码
神兽护体,代码无bug.经常看到代码注释的各种形状,这是一种程序员情怀.那么,如何能写出零 Bug 的代码呢,来看看@码农翻身 的这篇手册--零Bug的代码是怎么炼成的. 写零 Bug 一定少不了代码 ...
随机推荐
- Django框架(十六)-- 中间件、CSRF跨站请求伪造
一.什么是中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出 二.中间件的作用 如果你想修改请求,例如被传送到view ...
- linux date 设置系统时间
设置 系统时间 注意时间格式 date -s "date" [root@localhost c]# date -s "2019-05-29 10:58:00" ...
- NACOS升级操作
Server端 0.8.0及以上版本: 解压安装包后替换{nacos.home}/target/nacos-server.jar 删除{nacos.home}/plugins/cmdb/及{nacos ...
- adb命令之解锁打卡
adb devicesadb shell input keyevent 26 按手机电源键adb shell input swipe 400 1080 40 ...
- 2019面向对象程序设计(Java) 第17周-18周学习指导及要求
2019面向对象程序设计(Java)第17周-18周学习指导及要求 (2019.12.20-2019.12.31) 学习目标 (1) 理解和掌握线程的优先级属性及调度方法: (2) 掌握线程同步的 ...
- 201871020225-牟星源《面向对象程序设计(java)》第6-7周学习总结
201871020225-牟星源<面向对象程序设计(java)>第6-7周学习总结 博文正文: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu- ...
- 微信小程序,知识点
对于小程序的授权,只要用户授权一次,该授权关系就会记录在后台,除非删除小程序,或者用户在设置中关闭该授权. 官方文档: https://developers.weixin.qq.com/minipro ...
- day6_7.4总结数据类型的可变不可变
续昨天: 列表的常用方法: 1.chear() 用途:清空列表,其返回值无,返回none. list1=[1,2,3,4,5] a=list1.clear() print(list1) print(a ...
- 洛谷 P1628 合并序列
洛谷 P1628 合并序列 题目传送门 题目描述 有N个单词和字符串T,按字典序输出以字符串T为前缀的所有单词. 输入格式 输入文件第一行包含一个正整数N: 接下来N行,每行一个单词,长度不超过100 ...
- czy的后宫5
题目描述 Description \(czy\) 要召集他的妹子,但是由于条件有限,可能每个妹子不能都去,但每个妹子都有一个美丽值,\(czy\) 希望来的妹子们的美丽值总和最大(虽然--). \(c ...