10年前的3月28日,Go Team发表了一篇 Go version 1 is released[1] 的博客,宣告Go 1.0版本正式发行。此后Go团队大致以半年一个版本的进度,为Go语言及工具链赋予更多特性与功能。
出身名门巨匠,发轫之始便锋芒尽显。激荡10年间,尤是在云时代,有越来越多的基础设施与核心应用由Go开发或重构,也有越来越多的软件开发人员,充满热忱地成为Gopher。
最近不算太多的空余时间,交付给了 The Go Blog[2] 上的文章。仔细阅读了各个版本新增的feature,如Go 1.1 `P`及竞态检测的引入,G0 1.3对垃圾回收和栈的优化,sync.Pool的引入,Go 1.7 context包的“转正”等。
同时也在想一个问题:新feature的不断引入,如何保证对旧有代码的兼容?Python开发者想必对此更有共鸣---升级到Python3的代价,是之前基于Python2开发的代码无法正常运行。
而Go在发布1.0版本时,就同时附带了一份兼容性说明文档[3] 。该文档承诺,Go 的未来版本会尽可能确保向后兼容性(Backward Compatibility),不会破坏现有程序。
It is intended that programs written to the Go 1 specification
will continue to compile and run correctly, unchanged,
over the lifetime of that specification.
At some indefinite point, a Go 2 specification may arise,
but until that time, Go programs that work today should
continue to work even as future "point" releases of
Go 1 arise (Go 1.1, Go 1.2, etc.).
所谓向后兼容,即较高版本的程序能正常处理较低版本程序的数据(代码)。简而言之,在未来也许可能破坏兼容性的Go 2.0之前,基于Go 1.0写的程序,在10年后的Go 1.18版本上依然可以正常编译和运行。
(反之则不然,基于Go 1.16可正常编译&运行的代码,用Go 1.11版本,则可能编译不通过;同样,用Java 17开发并打的jar包,用Java 8运行会报错)
因为“前”“后”的二义性,一般可能会认为向后兼容是向以后的版本兼容,向前兼容是向之前的版本兼容,这理解其实是错误的
为此之前特意写了篇博客[4]。
Go承诺的是向后兼容(Backward Compatibility),所有的基准点和着眼点都是现在,是此刻。我需要回头需要转身向后面,去兼容之前的版本。即「新瓶可以装旧酒」。
但尴尬的是,在阅读10年前的Go 1.0版本发行说明时,却赫然看到了如下这样的描述,不啻晴天霹雳----是我之前自以为是的标准有误吗?总不能是Go Team对这个概念理解有误吧...
但还是本着“有理有据,即便错了,虽败犹荣” 的心态,不要怂,就是干,在我29岁生日那晚,提交了一个mr:
Reviewer选择了Ian Lance Taylor,这位毕业于耶鲁大学,常年活跃在Go社区的大佬不多时便给予了回复:
即 「Go 低版本」 向前兼容高版本的Go(向时间轴的右侧,未来), 「Go 高版本」向后兼容低版本的Go(向时间轴的左侧,以前)。
不过,Go 1.11兼容未来的Go 1.17,指的究竟是Go本身,还是指用Go编写的应用程序(数据)? 基于Go 1.11写的程序自然可以被后来的Go 1.17正常执行,我的理解,这应该说明Go具有向后兼容;而Go 1.11很可能无法执行Go 1.17写的程序(如用到了Go 1.16新增的特性),则说明Go不具备向前兼容...
大佬已有断言,不再过分深究。还是在此记录下我的疑惑。
[1]
文章: https://go.dev/blog/go1
[2]
文章: https://go.dev/blog/all
[1]
文章: https://go.dev/doc/go1compat
[1]
文章: https://dashen.tech/2022/02/03/%E5%90%91%E5%89%8D%E5%85%BC%E5%AE%B9%E4%B8%8E%E5%90%91%E5%90%8E%E5%85%BC%E5%AE%B9/