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 代码的更多相关文章

  1. 如何写出优雅的CSS代码 ?(转)

    对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于团队合作和后期的维护:而有的混 ...

  2. 如何写出优雅的css代码 ?

    如何写出优雅的css代码 ? 对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于 ...

  3. 如何写出优雅的JavaScript代码 ? && 注释

    如何写出优雅的JavaScript代码 ? 之前总结过一篇<如何写出优雅的css代码?>, 但是前一段时间发现自己的js代码写的真的很任性,没有任何的优雅可言,于是这里总结以下写js时应当 ...

  4. 【原创】怎样才能写出优雅的 Java 代码?这篇文章告诉你答案!

    本文已经收录自 JavaGuide (59k+ Star):[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识. 本文比较简短,基本就是推荐一些对于写好代码非常有用的文章或者 ...

  5. 深入了解Promise对象,写出优雅的回调代码,告别回调地狱

    深入浅出了解Promise 引言 正文 一.Promise简介 二.Promise的三种状态 三.函数then( ) 四.函数catch( ) 五.函数finally( ) 六.函数all( ) 七. ...

  6. 如何写出优雅的Python代码?

    有时候你会看到很Cool的Python代码,你惊讶于它的简洁,它的优雅,你不由自主地赞叹:竟然还能这样写.其实,这些优雅的代码都要归功于Python的特性,只要你能掌握这些Pythonic的技巧,你一 ...

  7. 如何写出优雅兼备可读性的javascript代码

    即或是最简单的需求,不同的程序员也会写出不一样的代码: 需求:充值程序过虑不符合条件的充值金额,即只能充入100.200.500.1000金额,其它过虑: 1.菜鸟程序员可能会这样写,虽然可读性强,代 ...

  8. 如何用java写出无副作用的代码

    搞java的同学们可能对无副作用这个概念比较陌生,这是函数式编程中的一个概念,无副作用的意思就是: 一个函数(java里是方法)的多次调用中,只要输入参数的值相同,输出结果的值也必然相同,并且在这个函 ...

  9. fir.im Weekly - 如何写出零 bug 的代码

    神兽护体,代码无bug.经常看到代码注释的各种形状,这是一种程序员情怀.那么,如何能写出零 Bug 的代码呢,来看看@码农翻身 的这篇手册--零Bug的代码是怎么炼成的. 写零 Bug 一定少不了代码 ...

随机推荐

  1. java 获取安全随机字符

    private static final char[] CHAR_32 = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', ...

  2. 阿里云Web应用防火墙采用规则引擎、语义分析和深度学习引擎相结合的方式防护Web攻击

    深度学习引擎最佳实践 {#concept_1113021 .concept} 阿里云Web应用防火墙采用多种Web攻击检测引擎组合的方式为您的网站提供全面防护.Web应用防火墙采用规则引擎.语义分析和 ...

  3. Nginx 初步认识

    序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. Nginx功能丰富,可作为HTTP服务器,也 ...

  4. Linux(CentOS)上,安装了Apache(httpd)后,其他的电脑无法访问的原因

    今天试了下在虚拟机上利用CentOS系统的yum命令安装好了httpd(apache2.2),然后在windows系统下访问此虚拟机的ip地址,却访问不了. 因为前段时间有知道过iptable的限制, ...

  5. css,区别pc端ipad端的样式

    摘自: http://blog.csdn.net/pm_mybook/article/details/54602107 /* 横屏 */ @media all and (orientation:lan ...

  6. 【Spring IoC】IoC容器初始化(二)

    Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动. 具体来说这个启动过程包括三个基本过程: BeanDefinition的Resource定位 BeanDefi ...

  7. JDOJ 1065 打倒苏联修正主义

    JDOJ 1065 https://neooj.com/oldoj/problem.php?id=1065 题目描述 [”客观”背景]苏修是苏联修正主义的简称.从1956年到1966年的10年间,过去 ...

  8. 数据结构——顺序队列(sequence queue)

    /* sequenceQueue.c */ /* 顺序队列 */ #include <stdio.h> #include <stdlib.h> #include <std ...

  9. P3273 【[SCOI2011]棘手的操作】

    此题用可并堆勉强过,需加输入优化,但是这里有个问题就是set总是过不了一组数据,用multiset时间有点高,不懂这个问题,请懂此问题的给我留言. 左偏树+并查集 下面上代码: #include &l ...

  10. [LeetCode] 52. N-Queens II N皇后问题之二

    The n-queens puzzle is the problem of placing nqueens on an n×n chessboard such that no two queens a ...