命令 go fix 会把指定 代码包 的所有 Go 语言源码文件中的旧版本代码修正为新版本的代码。这里所说的版本即 Go 语言的版本。代码包的所有 Go 语言源码文件不包括其子代码包(如果有的话)中的文件。修正操作包括把对旧程序调用的代码更换为对新程序调用的代码、把旧的语法更换为新的语法,等等。

这个工具其实非常有用。在编程语言的升级和演进的过程中,难免会对过时的和不够优秀的语法及标准库进行改进。这样的改进对于编程语言的向后兼容性是个挑战。我们在前面提到过向后兼容这个词。简单来说,向后兼容性就是指新版本的编程语言程序能够正确识别和解析用该编程语言的旧版本编写的程序和软件,以及在新版本的编程语言的运行时环境中能够运行用该编程语言的旧版本编写的程序和软件。对于Go语言来说,语法的改变和标准库的变更都会使得用旧版本编写的程序无法在新版本环境中编译通过。这就等于破坏了Go语言的向后兼容性。对于一个编程语言、程序库或基础软件来说,向后兼容性是非常重要的。但有时候为了让软件更加优秀,软件的开发者或维护者不得不在向后兼容性上做出一些妥协。这是一个在多方利益之间进行权衡的结果。本小节所讲述的工具正是 Go 语言的创造者们为了不让这种妥协给语言使用者带来困扰和额外的工作量而编写的自动化修正工具。这也充分体现了 Go 语言的软件工程哲学。下面让我们来详细了解它们的使用方法和内部机理。

命令 go fix 其实是命令 go tool fix 的简单封装。这甚至比 go fmt 命令对 gofmt 命令的封装更简单。像其它的 Go 命令一样,go fix 命令会先对作为参数的 代码包导入路径 进行验证,以确保它是正确有效的。像在本小节开始处描述的那样,go fix 命令会把有效代码包中的所有 Go 语言源码文件作为多个参数传递给 go tool fix 命令。实际上,go fix 命令本身不接受任何标记,它会把加入的所有标记都原样传递给 go tool fix 命令。go tool fix 命令可接受的标记如下表。

表0-15 go tool fix 命令的标记说明

标记名称 标记描述
-diff 不将修正后的内容写入文件,而只打印修正前后的内容的对比信息到标准输出。
-r 只对目标源码文件做有限的修正操作。该标记的值即为允许的修正操作的名称。多个名称之间用英文半角逗号分隔。
-force 使用此标记后,即使源码文件中的代码已经与 Go 语言的最新版本相匹配了,也会强行执行指定的修正操作。该标记的值就是需要强行执行的修正操作的名称,多个名称之间用英文半角逗号分隔。

在默认情况下,```go tool fix``` 命令程序会在目标源码文件上执行所有的修正操作。多个修正操作的执行会按照每个修正操作中标示的操作建立日期以从早到晚的顺序进行。我们可以通过执行```go tool fix -?```来查看```go tool fix```命令的使用说明以及当前支持的修正操作。 与本书对应的Go语言版本的```go tool fix```命令目前只支持两个修正操作。一个是与标准库代码包```go/printer```中的结构体类型```Config```的初始化代码相关的修正操作,另一个是与标准库代码包``net```中的结构体类型```IPAddr```、```UDPAddr```和```TCPAddr```的初始化代码相关的修正操作。从修正操作的数量来看,自第一个正式版发布以来,Go语言的向后兼容性还是很好的。从 Go 语言官网上的说明也可以获知,在 Go 语言的第二个大版本(Go 2.x)出现之前,它会一直良好的向后兼容性。 值得一提的是,上述的修正操作都是依靠 Go 语言的标准库代码包```go```及其子包中提供的功能来完成的。实际上,```go tool fix```命令程序在执行修正操作之前,需要先将目标源码文件中的内容解析为一个抽象语法树实例。这一功能其实就是由代码包```go/parser```提供的。而在这个抽象语法树实例中的各个元素的结构体类型的定义以及检测、访问和修改它们的方法则由代码包```go/ast```提供。有兴趣的读者可以阅读这些代码包中的代码。这对于深入理解 Go 语言对代码的静态处理过程是非常有好处的。 回到正题。与```gofmt```命令相同,```go tool fix```命令也有交互模式。我们同样可以通过执行不带任何参数的命令来进入到这个模式。但是与```gofmt```命令不同的是,我们在```go tool fix```命令的交互模式中输入的代码必须是完整的,即必须要符合 Go 语言源码文件的代码组织形式。当我们输入了不完整的代码片段时,命令程序将显示错误提示信息并退出。示例如下:

hc@ubt:~$ go tool fix -r='netipv6zone'

a := &net.TCPAddr{ip4, 8080} 

standard input:1:1: expected 'package', found 'IDENT' a

相对于上面的示例,我们必须要这样输入源码才能获得正常的结果:

hc@ubt:~$ go tool fix -r='netipv6zone' 

package main

import ( "fmt" "net" )

func main() {
addr := net.TCPAddr{"127.0.0.1", 8080}
fmt.Printf("TCP Addr: %s\n", addr)
} standard input: fixed netipv6zone package main import ( "fmt" "net" ) func main() {
addr := net.TCPAddr{IP: "127.0.0.1", Port: 8080}
fmt.Printf("TCP Addr: %s\n", addr)
}

上述示例的输出结果中有这样一行提示信息:“standard input: fixed netipv6zone”。其中,“standard input”表明源码是从标准输入而不是源码文件中获取的,而“fixed netipv6zone”则表示名为netipv6zone 的修正操作发现输入的源码中有需要修正的地方,并且已经修正完毕。另外,我们还可以看到,输出结果中的代码已经经过了格式化。

摘自:

http://wiki.jikexueyuan.com/project/go-command-tutorial/0.10.html

【Go命令教程】10. go fix 与 go tool fix的更多相关文章

  1. 【Go命令教程】命令汇总

    [Go命令教程]1. 标准命令详解 [Go命令教程]2. go build [Go命令教程]3. go install [Go命令教程]4. go get [Go命令教程]5. go clean [G ...

  2. 【译】ASP.NET MVC 5 教程 - 10:添加验证

    原文:[译]ASP.NET MVC 5 教程 - 10:添加验证 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效. DRY 原则 ASP.NET M ...

  3. 痞子衡嵌入式:第一本Git命令教程(0)- 索引

    大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家讲的是Git命令汇编,共12篇文章,循序渐进地介绍Git操作的完整过程. 在开始Git课程之前,需要先跟大家普及2个重要概念(四度空间.四种状 ...

  4. 天河2号-保持使用yhrun/srun时连接不中断 (screen 命令教程 )

    问题重述: 当我们使用天河机进行并行程序实验的时候,都会使用到yhrun/srun命令.在超算环境下,yhrun 命令用来进行提交交互式作业,有屏幕输出.但是容易受到网络波动影响导致断网或者关闭窗口最 ...

  5. Windows 批处理(cmd/bat)常用命令教程

    Windows批处理(cmd/bat)常用命令教程 简单详细,建议收藏 常见问题: 1.如果你自己编写的.bat文件,双击打开,出现闪退 2.批处理.bat 文件中输出中文乱码 解决方法在文章末尾! ...

  6. [译]Vulkan教程(10)交换链

    [译]Vulkan教程(10)交换链 Vulkan does not have the concept of a "default framebuffer", hence it r ...

  7. node-webkit教程(10)Platform Service之File dialogs

    node-webkit教程(10)Platform Service之File dialogs 文/玄魂 目录 node-webkit教程(10)Platform Service之File dialog ...

  8. Make 命令教程 -- 阮一峰

    摘自http://www.ruanyifeng.com/blog/2015/02/make.html Make 命令教程 作者: 阮一峰 日期: 2015年2月20日 代码变成可执行文件,叫做编译(c ...

  9. Linux pwn入门教程(10)——针对函数重定位流程的几种攻击

    作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...

随机推荐

  1. 上传插件dropzone.js实例

    dropzone.js默认是Ajax上传图片给服务器,那么如何获取到图片名呢?其实我们是可以通过dropzone的success函数获取到服务器返回的数据 dropzone.js在HTML的配置如下: ...

  2. Java Service Wrapper将java程序设置为服务

    有时候我们希望我们java写的程序作为服务注册到系统中,Java Service Wrapper(下面简称wrapper)是目前较为流行的将Java程序部署成Windows服务的解决方案, 本文将讨论 ...

  3. InteliJ IDEA 简单使用:配置项目所需jdk

    1:配置项目所需jdk: File->Project Structure 弹出如下界面: 首先选中SDKs,会出现下图界面:点击“+”标志弹出Add New SDK 然后选择JDK,会弹出路径框 ...

  4. (原创)关于viewpager嵌套listview居中显示的问题

    今天折腾了半天自定义控件的问题,如下图所示,我们UI设计了一种可以左右滑动的列表,而列表中又包含了listview.而且要居中显示listview 我一看UI,心想简单,不就是根据datas的数目进行 ...

  5. 6. 缓存 - 《APS.NET本质论》

    CaChe是ASP.NET中唯一可以根据服务器使用情况,动态管理内存使用的状态管理方案.我们通过每个缓存数据的键值字符串来区分缓存的数据. 简单案例来说.将数据从数据库/文件取出放在服务器内存中,后来 ...

  6. Java编程的逻辑 (68) - 线程的基本协作机制 (下)

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  7. hdu 5003 模拟水题 (2014鞍山网赛G题)

    你的一系列得分 先降序排列 再按0.95^(i-1)*ai 这个公式计算你的每一个得分 最后求和 Sample Input12530 478Sample Output984.1000000000 # ...

  8. CentOS6下Jenkins连接Git服务器出错的问题

    今天研究GitLab+Jenkins自动集成时,出现Failed to connect to repository : Command "git config --local credent ...

  9. Linux 获取目录中最后一个文件的名字

    find /application/docker_hub/logs/fof1private/amount_dev -type l | xargs basename

  10. php 结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...