乐趣区

关于后端:Go-deadcode查找没意义的死代码对于维护项目挺有用

大家好,我是煎鱼。

还记得我前两年在深圳加入了个技术大会,其中一个议题是携程的一个大佬分享他在日常工作中,发现一大堆过期的无意义代码和逻辑,导致大家工作较为繁琐且较为辛苦的状况。

携程应该是 Java 利用为主,他基于 Java 各种钻研,通过 JVM 内参数联合各种伎俩找到了无意义的死代码,并通过灰度机制等实现了逐渐上线和替换。

最近 Go 官网也终于有了相似的工具,明天分享给大家,能够继续关注!

用 deadcode 检测代码

广泛来讲,作为 Go 我的项目源代码一部分,但在任何执行过程中都无奈涉及的函数被称为 “ 死代码 ”,它们会连累代码库的保护工作。

也会造成程序员在浏览代码时的认知累赘,看了半天发现这代码基本没用。或是莫名其妙就被引入模块依赖里里。难堪得很。

当初咱们能够用 deadcode 来辨认他。装置形式如下:

$ go install golang.org/x/tools/cmd/deadcode@latest
$ deadcode -help
The deadcode command reports unreachable functions in Go programs.

Usage: deadcode [flags] package...

以下是一个简略 Demo:

func main() {
    var g Greeter
    g = Helloer{}
    g.Greet()}

type Greeter interface{Greet() }

type Helloer struct{}
type Goodbyer struct{}

var _ Greeter = Helloer{}
var _ Greeter = Goodbyer{}

func (Helloer) Greet()  { hello() }
func (Goodbyer) Greet() { goodbye() }

func hello()   { fmt.Println("你好,煎鱼!") }
func goodbye() { fmt.Println("再见,煎鱼!") }

运行后果:

$ go run main.go
你好,煎鱼!

咋一眼一看,可能没法晓得是哪块代码没用到。还须要多看两眼。

这时候咱们只须要借助 deadcode 工具去扫描,一下子就能失去后果了。

执行如下命令并查看输入后果:

$ deadcode .
main.go:20:17: unreachable func: Goodbyer.Greet
main.go:23:6: unreachable func: goodbye

检测后果通知咱们 goodbye 函数和 Goodbyer.Greet 办法都无法访问。也就是这个代码自身的存在是没有运行意义的。

如果你心愿革除这些骚扰代码,就能够根据这个后果去做删除代码了。

同时也能够借助命令的子选项 -whylive,让检测工具给咱们解释为什么 greet.hello 函数是无效的。

如下解释后果:

$ deadcode -whylive=example.com/greet.hello .
                  example.com/greet.main
dynamic@L0008 --> example.com/greet.Helloer.Greet
 static@L0019 --> example.com/greet.hello
                   example.com/greet.main
  ...

该命令会把 main 开始到函数调用的过程打印进去,作为一种解释。证实这个函数的确是存在应用的。

留神点和发现机制

须要注意的是:deadcode 工具,必须要蕴含 main 函数。话中有话就是其检测链路是从 main 函数开始的。

否则会产生如下的报错信息:

$ deadcode .
deadcode: no main packages

deadcode 工具自身会加载、解析和类型查看指定的包,而后将其转换为相似编译器的两头示意模式。

而后会应用 Rapid Type Analysis(RTA)的算法来建设可达函数集,最后只包含每个次要包的入口点:main 函数和包初始化函数(调配全局变量并调用名为 init 的函数)。

RTA 剖析每个可达函数的语句体以收集三种类型的信息:间接调用的函数汇合、通过接口办法进行的动静调用汇合以及转换为接口的类型汇合。

因而他必须依赖 main 函数作为主入口来做调用链路剖析。当然了,这也是绝对失常的。总得有个“客户端”来做开始逻辑。

咱们能够定期在 Go 我的项目上运行 deadcode 命令(特地是在重构工作之后),以帮忙辨认程序中不再须要的局部。

但须要注意的是,deadcode 工具还是在倒退阶段。简单场景下,可能无奈保障 100% 的准确率,咱们最好还是要本人做一遍 double check 和灰度上线。

总结

明天基于官网的《Finding unreachable functions with deadcode》给大家分享了 deadcode 工具的应用和机制。

整体上来讲,还是十分乐见这个工具的诞生和倒退的。历史我的项目保护旧了,很多中央删删改改,沉积久了后,的确会给大家开发造成不少的认知累赘和保护老本。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言能够看 Go 学习地图和路线,欢送 Star 催更。

举荐浏览

  • Go1.22 新个性:for 循环不再共享循环变量,且反对整数范畴
  • Go1.22 新个性:Slices 变更 Concat、Delete、Insert 等函数,对开发挺有帮忙!
  • Go1.22 新个性:新的 math/rand/v2 库,更快更规范!
退出移动版