在撰写《Go 1.14中值得关注的几个变化》这篇文章时,我使用的试验环境为我的2019款 MacPro,OS版本:10.14.6。我通过下载 https://dl.google.com/go/go1.14.darwin-amd64.tar.gz并解压的方式安装的Go 1.14版本。在我的工作环境中,我通常通过变更GOROOT的方式来使用不同的Go版本。但在进行Go 1.14新增的overlapping interface的实验时,我遇到了一个问题。本文记录的就是这个问题的发现和解决过程,以备自己备忘,也希望能给广大Gopher带来启发。

1. 问题现象

在我进行overlapping interface试验时,我使用go 1.14编译器编译下面的代码:

// https://github.com/bigwhite/experiments/blob/master/go1.14-examples/overlapping_interface.gopackage footype I interface {    f()    String() string}type J interface {    g()    String() string}type IJ interface {    I    J}

但出乎意料的是我得到了如下的结果:

$go build overlapping_interface.go# command-line-arguments./overlapping_interface.go:14:2: duplicate method String

我一脸懵逼啊!我靠!Go 1.14的新增的overlapping interface机制居然不好用!之后我的第一反应就是检查是不是我的当前窗口中GOROOT设置有误,结果:GOROOT设置完全没错!

于是我又切换到一个Ubuntu 18.04环境下,同样用Go 1.14版本(for linux)编译上述代码,这回编译很顺利,没有报出像MacOS那样的错误。

接下来进入胡思乱想状态:) 难道是Go team在打包go1.14.darwin-amd64.tar.gz是忘记了这个功能?.... .....

2. 问题分析过程

我首先到go项目的issue列表查是否有人遇到与我相同的问题,居然没找到,基本肯定是我自己环境的问题了。于是提了一个issue(https://github.com/golang/go/issues/37728),看看有谁能帮忙分析一下原因。

不久,Go核心开发团队的Keith Randall提供了一些信息和诊断思路。首先他在他自己的Mac环境无法重现该问题,并也怀疑是不是我的安装方式和环境变量设置的问题。

于是,我尝试了更换一种Go 1.14的安装方式来重新安装Go 1.14 for MacOS:

$go get golang.org/dl/go1.14go: finding golang.org/dl latestgo: downloading golang.org/dl v0.0.0-20200302224518-306f3096cb2fgo: extracting golang.org/dl v0.0.0-20200302224518-306f3096cb2f$go1.14 downloadDownloaded   0.0% (    14448 / 124931758 bytes) ...Downloaded   0.3% (   391280 / 124931758 bytes) ...... ...Downloaded  92.5% (115554516 / 124931758 bytes) ...Downloaded 100.0% (124931758 / 124931758 bytes)Unpacking /Users/tonybai/sdk/go1.14/go1.14.darwin-amd64.tar.gz ...Success. You may now run 'go1.14'$go1.14 envGO111MODULE="on"GOARCH="amd64"GOBIN=""GOCACHE="/Users/tonybai/Library/Caches/go-build"GOENV="/Users/tonybai/Library/Application Support/go/env"GOEXE=""GOFLAGS=""GOHOSTARCH="amd64"GOHOSTOS="darwin"GOINSECURE=""GONOPROXY=""GONOSUMDB=""GOOS="darwin"GOPATH="/Users/tonybai/Go"GOPRIVATE=""GOPROXY="https://goproxy.cn,direct"GOROOT="/Users/tonybai/sdk/go1.14"GOSUMDB="off"GOTMPDIR=""GOTOOLDIR="/Users/tonybai/sdk/go1.14/pkg/tool/darwin_amd64"GCCGO="gccgo"AR="ar"CC="clang"CXX="clang++"CGO_ENABLED="1"GOMOD="/dev/null"CGO_CFLAGS="-g -O2"CGO_CPPFLAGS=""CGO_CXXFLAGS="-g -O2"CGO_FFLAGS="-g -O2"CGO_LDFLAGS="-g -O2"PKG_CONFIG="pkg-config"GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/cz/sbj5kg2d3m3c6j650z0qfm800000gn/T/go-build236598550=/tmp/go-build -gno-record-gcc-switches -fno-common"

我使用renew后的go1.14再来编译最初那段包含了overlapping interface的代码:

➜  /Users/tonybai/Go/src/github.com/bigwhite/experiments/go1.14-examples git:(master) $go1.14 versiongo version go1.14 darwin/amd64➜  /Users/tonybai/Go/src/github.com/bigwhite/experiments/go1.14-examples git:(master) $go1.14 build overlapping_interface.go# command-line-arguments./overlapping_interface.go:14:2: duplicate method String

问题依旧!

为了给Keith Randall提供更多有用信息,我在build时传入-x -v参数:

➜  /Users/tonybai/Go/src/github.com/bigwhite/experiments/go1.14-examples git:(master) $go1.14 build -x -v overlapping_interface.goWORK=/var/folders/cz/sbj5kg2d3m3c6j650z0qfm800000gn/T/go-build369480074command-line-argumentsmkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configEOFcd /Users/tonybai/Go/src/github.com/bigwhite/experiments/go1.14-examples/Users/tonybai/sdk/go1.14/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath "$WORK/b001=>" -p command-line-arguments -lang=go1.12 -complete -buildid 00YuEePKlhV_qKTnJcVK/00YuEePKlhV_qKTnJcVK -goversion go1.14 -D _/Users/tonybai/Go/src/github.com/bigwhite/experiments/go1.14-examples -importcfg $WORK/b001/importcfg -pack -c=4 ./overlapping_interface.go# command-line-arguments./overlapping_interface.go:14:2: duplicate method String

一段时间后,眼尖的Keith Randall发现了蛛丝马迹:-lang=go 1.12。在我提供的上面build日志中,"-lang=1.12"被传给了Go 1.14 compiler,于是虽然贵为go 1.14版本编译器,但它也只能按照go 1.12版本的语法规范对我的代码进行检查和编译,这就是“罪魁祸首”,没跑了!

3. 问题解决

但是"-lang=1.12"怎么就凭空出现传给了Go 1.14编译器了呢?我查了所有编译器相关的环境变量,也没看到哪里设置了-lang=1.12。正当我处于迷茫状态时,突然go.mod这个文件名浮现在我的脑海中:go.mod中除了module名、一堆require、replace语句之外,还有go 1.12引入的go指示信息(directive)! 顿悟!!!

上面所有的go build执行都是在我本地的/Users/tonybai/go/src/github.com/bigwhite/experiments/go1.14-examples下执行的。而github.com/bigwhite/experiments这个repo的顶层go.mod文件内容如下:

module github.com/bigwhite/experimentsgo 1.12

在Go 1.12的release note中,我们看到这样一段说明:

The go directive in a go.mod file now indicates the version of the language used by the files within that module.go.mod文件中的go指示器指示该当前module中文件使用的Go语言版本。

当前,我的go.mod中go指示器指示的版本为go 1.12,那么即便是使用Go 1.14版本编译器编译该module下的文件,使用的也是go 1.12的语法。

解决方法:升级go.mod中的go指示器版本为go 1.14。升级后问题迎刃而解。

4. 小结

目前仅仅在使用比go.mod中go指示器版本低的go编译器对module下源文件进行编译,在报错的时候才会给出版本不匹配的提示。但是如果使用比go指示器版本高的编译器编译,即便出错,也没有警告提示。因此,在升级go版本时,要小心维护go.mod中的go directive,使其与你使用的go compiler版本匹配


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://51smspush.com/ smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展;短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻)归档仓库 - https://github.com/bigwhite/gopherdaily

我的联系方式:

微博:https://weibo.com/bigwhite20xx 微信公众号:iamtonybai 博客:tonybai.com github: https://github.com/bigwhite

微信赞赏:

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

go build 无文件_小心go.mod中的go directive相关推荐

  1. go build 无文件_用一句话描述Go语言的命令

    Go命令是管理Go资源的工具 有一些命令是非常常用的,比如 run.build.get.test.get,有一些命令在使用IDE后很少会用到,IDE代劳了,比如fmt.vet. 把所有命令列出来,了解 ...

  2. go build 无文件_Go学习_30_Golang代码性能分析工具

    Golang内置了一些性能分析工具,可以将性能分析的结果文件输出,我们可以使用图形化的工具查看分析结果,在使用这些工具之前,我们需要安装一些工具,以便于查看分析文件. 为了支持查看图形化分析结果,首先 ...

  3. go build 无文件_Go之Gin+Vue开发一个线上外卖应用

    我们将开始使用Gin框架开发一个api项目,我们起名为:云餐厅.如同饿了么,美团外卖等生活服务类应用一样,云餐厅是一个线上的外卖应用,应用的用户可以在线浏览商家,商品并下单. 该项目分为客户端和服务端 ...

  4. nio 读取目录所有文件_在NIO.2中使用文件和目录

    nio 读取目录所有文件 在先前的文章中,我讨论了文件和目录的创建( 创建文件和目录 )以及选择( 列出和过滤目录内容 ). 采取的最后一个合乎逻辑的步骤是探索我们如何使用它们以及如何使用它们. 这是 ...

  5. win10无法装载iso文件_在Win10系统中如何装载ISO镜像文件?

    windows 10系统在默认未解压的状态下是以iso格式存在的镜像文件.在Win10系统中该如何装载win10系统的镜像呢?一般来说iso文件都是在DVD光盘中的文件,但大多数的用户都已经不适用DV ...

  6. load python txt文件_详解Python中numpy.loadtxt()读取txt文件

    为了方便使用和记忆,有时候我们会把 numpy.loadtxt() 缩写成np.loadtxt() ,本篇文章主要讲解用它来读取txt文件. 读取txt文件我们通常使用 numpy 中的 loadtx ...

  7. matlab分析xml文件_如何在Java中读取XML文件(DOM分析器)

    matlab分析xml文件 Today we will learn how to read the XML file in Java. We will also learn how to parse ...

  8. go build 无文件_GO笔记之详解GO的编译执行流程

    上篇文章介绍了Golang在不同系统下的安装,并完成了经典的Hello World案例.在这个过程中,我们用到了go run命令,它完成源码从编译到执行的整个过程. 今天来详细介绍下这个过程.简单理解 ...

  9. go build 无文件_Go 质量保证:集成测试(1) 用 Docker 执行测试

    点击上方蓝色"Go语言中文网"关注我们,领全套Go资料,每天学习 Go 语言 简介 "测试会带来失败,而失败会带来理解." -- Burt Rutan Burt ...

最新文章

  1. Python 中的魔术方法(双下划线开头和结尾的方法)
  2. VMware vSphere 5.1 学习系列之:安装 vCenter Server
  3. php用array_merge实现无限级分类
  4. FastReport.Net 使用字符串
  5. 【转】Android4.4 之Bluetooth整理
  6. cdf日上免税店_cdf会员购吐槽大会!从上海日上开始!
  7. 内卷化的信贷行业,如何做好信贷风控规则的挖掘
  8. 不止 RTC 技术盛会,你还应该知道的声网给开发者的福利
  9. MAC常用快捷键和常规操作(一)
  10. C++ 回调函数简单示例
  11. 这一切,只因心中有梦
  12. c语言格式字符二进制,C语言printf如何输出二进制数格式?将十进制数转为二进制输出...
  13. 华为AI计算机,华为发布人工智能工程师认证(HCNA-AI),推动人工智能人才生态发展...
  14. 关于博客笔记大汇总,持续更新迭代
  15. EventBus实现原理
  16. [OHIF-Viewers]医疗数字阅片-医学影像-es6-Element.querySelector()
  17. 求助:MATLAB中实现卷积运算和理论分析中的卷积运算有什么区别?
  18. 一名大学毕业生的反思_反思我大学毕业时的软件工程师的第一年
  19. [vue] 无缝滚动 vue-seamless-scroll 滚动表格
  20. 【C++】【C++ Primer】8-IO库

热门文章

  1. 计算机简介、电脑常用快捷键、DOS命令、java环境搭建
  2. 何新生的英语史(七)—— 平淡期,重文化风俗俚语阶段
  3. 黄金 白银T+D 盈利计算器
  4. 东财《EXCEL在财务工作中的应用》综合作业
  5. 五分钟深入理解Handler
  6. 信号(2)信号处理器函数
  7. TensorRT实现RetinaFace推理加速(一)
  8. 8 个值得拥有的高逼格平面设计软件
  9. 1412: QAQ 君临天下 || 天行九歌 [区间]
  10. js 银行卡每四位加空格正则表达式