新的工具 Go fix

未匹配的标注

本文为官方 Go Blog 的中文翻译,详见 翻译说明

Russ Cox
2011 年 4 月 15 日

下一个版本的 Go 将在几个基本的 Go 程序包中对 API 进行重大更改. 实现一个 HTTP 服务器处理程序 的代码, 调用 net.Dial, 调用 os.Open, 或 使用反射程序包 除非已更新为使用新的 API. 虽然现在我们的发行版本 更稳定更不频繁, 这将是一种常态. 这些 API 更改中的每一个都在不同的每周快照中发生, 并且可能可以单独管理. 但是, 它们糅合到一起时需要大量的人力来更新现有代码.

Gofix 是一个新工具, 可减少更新现有代码所需的工作量. 它从源文件中读取程序, 查找旧 API 的使用, 将其重写为使用当前API, 然后将该程序写回到文件中. 并非所有的 API 更改都能保留旧 API 的所有功能, 因此 gofix 不能总是做得完美. 当 gofix 无法重写对旧 API 的使用时, 它将打印警告, 给出使用的文件名和行号, 以便开发人员可以检查并重写代码. Gofix 负责简单, 重复, 乏味的更改, 因此开发人员可以专注于真正值得关注的内容.

每次我们对 API 进行重大更改时, 都会在 gofix 中添加代码以尽可能多地进行转换. 当您更新到新的 Go 版本并且不再构建代码时, 只需在源目录上运行 gofix.

您可以扩展 gofix 以支持对自己的 API 的更改. gofix 程序是围绕名为 fixs 的插件的简单驱动程序, 每个插件都处理特定的 API 更改. 目前, 编写新的修复程序需要对 go/ast 语法树进行一些扫描和重写, 通常与 API 更改的复杂程度成正比. 如果您想知晓更多, 可参阅netdialFix, osopenFix, httpserverFix, 和 reflectFix 都是说明性示例, 以复杂度递增的顺序.

当然, 我们也编写 Go 代码, 并且这些 API 更改对我们代码的影响与您一样. 通常, 我们在更改 API 的同时编写 gofix 支持, 然后使用 gofix 在主源代码树中重写用法. 我们使用 gofix 来更新其他 Go 代码库和我们的个人项目. 当需要针对新的 Go 版本进行构建时, 我们甚至使用 gofix 更新 Google 的内部源代码树.

举个栗子, gofix 重写了如下代码 fmt/print.go 中的代码片段:

switch f := value.(type) {
case *reflect.BoolValue:
    p.fmtBool(f.Get(), verb, field)
case *reflect.IntValue:
    p.fmtInt64(f.Get(), verb, field)
// ...
case reflect.ArrayOrSliceValue:
    // 特殊的字节切片
    if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.Uint8 {
        // ...
    }   
// ...
}

使其适应新的反射 API:

switch f := value; f.Kind() {
case reflect.Bool:
    p.fmtBool(f.Bool(), verb, field)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    p.fmtInt64(f.Int(), verb, field)
// ...
case reflect.Array, reflect.Slice:
    // 特殊的字节切片.
    if f.Type().Elem().Kind() == reflect.Uint8 {
        // ...
    }   
// ...
}

几乎上面的每一行代码都以某种很小的方式改变. 重写涉及的更改是广泛的, 但几乎完全是机械的, 就是那种计算机更擅长做的事情.

Gofix 之所以可行, 是因为 Go 在其标准库中支持将 将 Go 源文件解析为语法树 以及 将这些语法树打印回Go源代码. 重要的是, Go 打印库以正式格式 ( 通常通过 gofmt 工具强制执行) 打印程序, 从而使 gofix 可以对 Go 程序进行机械更改, 而不会引起虚假的格式更改. 实际上, 创建 gofmt 的主要动机之一 (可能仅次于避免辩论某个特定括号的位置) 仅是像 gofix 一样简化了重写 Go 程序的工具的创建.

Gofix 已经使自己成为必不可少的东西. 特别是如果不进行自动转换, 最近的反射更改将变得不受欢迎, 并且非常需要重做反射 API. Gofix 使我们能够纠正错误或完全重新考虑软件包 API, 而不必担心转换现有代码的成本. 我们希望您发现 gofix 易用和方便性, 就像我们用的那样.

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/go-blog/introdu...

译文地址:https://learnku.com/docs/go-blog/introdu...

上一篇 下一篇
Summer
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~