本文视频地址
gofmt
Go 语言设计的指标之一就是解决大型软件系统的大规模开发的问题,解决大型团队的开发问题,Go 外围团队给它起了一个名字叫:规模化(scale)。
gofmt 是随同着 Go 语言诞生的第一批在“规模化”这个指标上的实际和尝试。gofmt 将对立的代码格调内化到 Go 语言之中,并和 Go 语言一起推广给所有 Go 开发者。在统一的代码格调下,Go 开发人员浏览和保护别人代码时,效率大幅。gofmt 代码格调曾经成为 Go 开发者的一种共识。如果你是 Go 开发人员,提交代码前应用 gofmt 格式化你的 Go 源码。
应用 gofmt
Go 1.14 之后,gofmt 工具是放在 Go 安装包中与 Go 编译器工具一并公布的,这足以阐明 gofmt 工具的重要水平,gofmt 放弃了 Go 语言“简略”的设计哲学,这点通过其帮忙手册即可看得出来:
gofmt -help
usage: gofmt [flags] [path ...]
-cpuprofile string
write cpu profile to this file
-d display diffs instead of rewriting files
-e report all errors (not just the first 10 on different lines)
-l list files whose formatting differs from gofmt's
-r string
rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
-s simplify code
-w write
一 应用 gofmt -s 简化你的代码
在 gofmt 中提供了 -s 选项,通过 gofmt -s 能够主动将遗留代码中的非简化代码主动转换为简化写法,并且没有副作用,因而个别“-s”选项都会是 gofmt 执行的默认选项。
二 应用 gofmt -r 执行代码“迭代更新”
代码更新迭代和重构是软件工程过程中的日常操作
-r string
rewrite rule (e.g., 'a[b:len(a)] -> a[b:]’)
gofmt -r 的原理就是在对源码进行从新格式化之前,搜寻源码是否有能够匹配 pattern 的表达式,如果有,将所有匹配到的后果替换为 replacement 表达式。gofmt 要求 pattern 和 replacement 都是非法的 Go 表达式。比方:
gofmt -r‘p[6:len(a)] -> p[6:]' -w person.go
下面 gofmt -r 命令执行的用意就是将源码文件 person.go 中能与 p[6:len(a)] 匹配的代码替换为 p[6:],而后再做从新格式化。
留神:上述命令中的 p 并不是一个具体的字符,而是代表的一个通配符。呈现在‘pattern -> replacement’的小写字母都会被视为通配符。因而下面的命令对上面的源码片段都能够胜利匹配:
- fmt.Println(b[6:len(b)])
+ fmt.Println(b[6:])
- v, err := s.r.Read(b.buf[6:len(b.buf)])
+ v, err := s.r.Read(b.buf[b.end:])
- foods = append(foods, persons[6:len(persons)])
+ foods = append(foods, persons[6:])
三 应用 gofmt -l 按格局要求输入文件列表
gofmt 提供了 -l 选项,能够按格局要求输入满足条件的文件列表。
gofmt -l ~/go/src/github.com/
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/main.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/pkg/util/util.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/360EntSecGroup-Skylar/excelize/styles.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/Unknwon/com/math.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/fvbock/endless/endless.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/go-openapi/spec/bindata.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/modern-go/concurrent/log.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/modern-go/concurrent/unbounded_executor.go
/Users/xxx/go/src/github.com/EDDYCJY/go-gin-example/vendor/github.com/modern-go/reflect2/reflect2.go
以上命令并不是只能独自应用,咱们也能够将他们组合起来应用。注:如果某门路下有很多不合乎 gofmt 格局的文件,这些文件也有可能会被一并输入。
3. 应用 go-imports
Go 编译器在编译源码时会对源码文件 import 的 package 进行查看:
1 源文件中没有应用但却导入了的 package
2 应用了但没有导入的包
以上两种状况 Go 编译器会报错。
那么有没有方法解决呢?于是,goimports 闪亮退场了,goimports 在 gofmt 的性能的根底上,减少了对 package 列表的保护性能,可依据源码的最新变动主动从导入包列表中增删包。装置 goimports 的办法很简略:
go get golang.org/x/tools/cmd/goimports
如果 go 编译器在 $GOPATH/bin 门路里,就会将 goimports 可执行文件放入该门路下,应该保障该门路在 $PATH 中即可。goimports 能够了解为 gofmt 上又封装了一层,并且 goimports 的命令行选项和参数与 gofmt 也非常相似:
usage: goimports [flags] [path ...]
-cpuprofile string
CPU profile output
-d display diffs instead of rewriting files
-e report all errors (not just the first 10 on different lines)
-format-only
if true, don't fix imports and only format. In this mode, goimports is effectively gofmt, with the addition that imports are grouped into sections.
-l list files whose formatting differs from goimport's
-local string
put imports beginning with this string after 3rd-party packages; comma-separated list
-memprofile string
memory profile output
-memrate int
if > 0, sets runtime.MemProfileRate
-srcdir dir
choose imports as if source code is from dir. When operating on a single file, dir may instead be the complete file name.
-trace string
trace profile output
-v verbose logging
-w write result to (source) file instead of stdout
4. 将 gofmt/goimports 与编辑器工具集成
日常 Go 开发人员多应用各种支流编辑器进行代码的编写、测试和重构工作,对代码的格式化个别是通过将 gofmt/goimports 与编辑器集成后在源文件保留时由编辑器主动调用 gofmt/goimports 实现的,简直不须要手工敲入 gofmt 命令对源码进行格式化的。
goland 是目前支流的 Go 语言开发工具,以此为例子,如下图所示: