Golang 更严格的代码格式化工具 gofumpt
一、前言
gofmt 是 golang 自带的代码自动格式化工具,是保证 Go 代码风格一致的大杀器。我们这次要推荐的 gofumpt 在 gofmt 的基础上添加了一系列更加严格的格式化规则,并保证了对 gofmt 的兼容。
二、gofumpt 简介
gofumpt(https://github.com/mvdan/gofumpt) fork 自 gofmt,支持与 gofmt 几乎相同的命令行参数,因此可以作为 gofmt 的直接替代品使用。gofumpt 是 gofmt 的"超集",经过 gofumpt 格式化的代码也符合 gofmt 的要求,其本身所扩展的格式化规则也可能在后续被集成进 gofmt。
gofumpt 有以下特点:
- 更多的格式化规则(参见 https://github.com/mvdan/gofumpt#Added-rules)
- 默认跳过对 vendor 的格式化
- 不对自动生成的代码应用扩展规则
- 不支持 -r 参数
三、安装、使用命令
安装命令:
go install mvdan.cc/gofumpt@latest
执行命令:
gofumpt -l -w .
四、使用举例
赋值运算符后面没有空行
func foo() {
foo :=
"bar"
}
改为 gofumpt 格式化后:
func foo() {
foo := "bar"
}
函数体周围没有空行
func foo() {
println("bar")
}
改为 gofumpt 格式化后:
func foo() {
println("bar")
}
函数应分隔 ‘) {’,其中缩进有助于可读性
func foo(s string,
i int) {
println("bar")
}
// With an empty line it's slightly better, but still not great.
func bar(s string,
i int) {
println("bar")
}
改为 gofumpt 格式化后:
func foo(s string,
i int,
) {
println("bar")
}
// With an empty line it's slightly better, but still not great.
func bar(s string,
i int,
) {
println("bar")
}
块中单个语句 (或注释) 周围没有空行
if err != nil {
return err
}
改为 gofumpt 格式化后:
if err != nil {
return err
}
在简单的错误检查之前没有空行
foo, err := processFoo()
if err != nil {
return err
}
改为 gofumpt 格式化后:
foo, err := processFoo()
if err != nil {
return err
}
复合文字应一致地使用换行符
// A newline before or after an element requires newlines for the opening and
// closing braces.
var ints = []int{1, 2,
3, 4}
// A newline between consecutive elements requires a newline between all
// elements.
var matrix = [][]int{
{1},
{2}, {
3,
},
}
改为 gofumpt 格式化后:
var ints = []int{
1, 2,
3, 4,
}
var matrix = [][]int{
{1},
{2},
{
3,
},
}
空字段列表应使用单行
var V interface {
} = 3
type T struct {
}
func F()
改为 gofumpt 格式化后:
var V interface{} = 3
type T struct{}
func F()
std
导入必须位于顶部的单独组中
import (
"foo.com/bar"
"io"
"io/ioutil"
)
改为 gofumpt 格式化后:
import (
"io"
"io/ioutil"
"foo.com/bar"
)
简短的case子句应采用单行
switch c {
case 'a', 'b',
'c', 'd':
}
改为 gofumpt 格式化后:
switch c {
case 'a', 'b', 'c', 'd':
}
多行顶级声明必须用空行分隔
func foo() {
println("multiline foo")
}
func bar() {
println("multiline bar")
}
改为 gofumpt 格式化后:
func foo() {
println("multiline foo")
}
func bar() {
println("multiline bar")
}
单个var声明不应使用括号分组
var (
foo = "bar"
)
改为 gofumpt 格式化后:
var foo = "bar"
连续的顶级声明应该组合在一起
var nicer = "x"
var with = "y"
var alignment = "z"
改为 gofumpt 格式化后:
var (
nicer = "x"
with = "y"
alignment = "z"
)
简单的var声明语句应该使用短赋值
var s = "somestring"
改为 gofumpt 格式化后:
s := "somestring"
默认情况下启用 ‘-s’ 代码简化标志
var _ = [][]int{[]int{1}}
改为 gofumpt 格式化后:
var _ = [][]int{{1}}
八进制整数文字应在使用Go 1.13及更高版本的模块上使用 ‘0o’ 前缀
const perm = 0755
改为 gofumpt 格式化后:
const perm = 0o755
不是Go指令的注释应该以空格开头
//go:noinline
//Foo is awesome.
func Foo() {}
改为 gofumpt 格式化后:
//go:noinline
// Foo is awesome.
func Foo() {}
复合文字不应具有前导或尾随空行
var _ = []string{
"foo",
}
var _ = map[string]string{
"foo": "bar",
}
改为 gofumpt 格式化后:
var _ = []string{
"foo",
}
var _ = map[string]string{
"foo": "bar",
}
字段列表不应有前导或尾随空行
type Person interface {
Name() string
Age() int
}
type ZeroFields struct {
// No fields are needed here.
}
改为 gofumpt 格式化后:
type Person interface {
Name() string
Age() int
}
type ZeroFields struct {
// No fields are needed here.
}
五、总结
gofumpt 是一款优秀的 go 代码格式化扩展工具,能够帮助我们进一步提升代码质量,来试试看吧!