当前位置: 首页 > 后端技术 > PHP

强化!Go将增强Go1的向后兼容性

时间:2023-03-29 20:28:44 PHP

大家好,我是建宇。前段时间我们在写Go1.20的新特性和变化的时候,发现了一个悖论。Go1有兼容性承诺,但如果发现错误,就会破坏兼容性。那么该怎么办?是大胆修改破坏,还是设计成打死不改?写了开头结果是正的,现在杨半康又回来更新了。Go1兼容性保证Go1中引入了Go兼容性保证《Go 1 and the Future of Go Programs》,即老版本的Go程序也可以在新版本的Go中正常运行。当然,凡事都有例外,比如安全问题。具体完整的规则如下:我们经常会接触到以下内容:安全问题:可能会发现Go规范或实现中的安全问题,其解决需要破坏兼容性。保留解决这些安全问题的权利。未指定的行为:虽然Go规范试图指定所有已知的行为,但仍有未定义的意外方面。在这方面可能会出现问题。规格错误:如果有必要解决规格(spec)中的不一致和不完整之处,我们保留解决此类问题的权利。除安全问题外,不会对规范进行不兼容的更改。问题/缺陷:如果编译器或库存在违反规范的缺陷,我们保留修复这些缺陷的权利。使用导入。导入:如果您使用导入。“路径”,导入包中定义的其他名称可能与未来版本中程序中定义的其他名称冲突。我们不建议使用import。在测试之外,使用它可能会导致程序在未来的版本中无法编译。对不安全库的引用:导入不安全的包可能取决于Go实现的内部属性。保留修改权。Go核心团队曾表示拥有10+年的Go1兼容性保障经验,这对Go团队和用户来说都是非常宝贵的。甚至在过去的两年里,Go团队和业界都将Go的快速发展归功于Go1兼容性保证的实施。它看起来仍然很结实。扩展Go向后兼容的背景虽然Go团队主观上认为自己做得更好,但发现仍然存在兼容性违规的情况。于是,Go的现任负责人@RussCox推出了《extending Go backward compatibility》。值得扩展Go1的向后兼容性以尝试减少破坏程序的频率,显式设置GODEBUG以方便声明更改何时适合使用和控制。简单来说,Go1兼容性承诺给Go带来了很大的好处,我们要继续扩大优势,拉长长板。怎么突然提起来了?为什么突然想做这个?因为RussCox最近和Kubernetes团队交谈发现,在过去的几年里,Go平均每年大约有一个Kubernetesbreakingchange。它认为Kubernetes当然不是孤例。虽然每年1次左右不是很频繁,但Go团队对Go1兼容性的目标是0。以下是Kubernetes重大变化的一些示例:有兴趣的同学可以仔细看看,考虑到大多数同学可能并不关心,所以我没有进一步展开。现有的与兼容性相关的GODEBUG设置包括以下内容:GODEBUG=asyncpreemptoff=1:禁用基于信号的Goroutine抢占,它偶尔会发现操作系统中的错误。GODEBUG=cgocheck=0:在运行时禁用CGO指针检查。GODEBUG=cpu.=off:在运行时禁止使用特定的CPU扩展。GODEBUG=http2client=0:为客户端禁用HTTP/2。GODEBUG=http2server=0:在服务器端禁用HTTP/2。GODEBUG=netdns=cgo:强制使用CGO解析器。GODEBUG=netdns=go:强制使用GoDNS解析器。扩大Go1兼容性保证在新的提案中,Go将规范化和扩大GODEBUG的使用,并会在go.mod中根据Go版本号设置相应的GODEBUG,以提供超越当前兼容性指南的兼容性。也就是说,将对之前的GODEBUG配置项进行扩展,扩大使用范围。新措施如下所示:承诺始终为兼容性指南允许的更改添加GODEBUG设置,但这仍有可能破坏大量实际程序。GODEBUG设置保证至少持续2年(4个版本)。这只是最低限度;会有例如:http2server,可能永远存在。提供运行时/指标计数器,可用于观察由GODEBUG设置引起的非默认行为。例如:/godebug/non-default-behavior/:events。在Gomodules主模块的go.mod中根据Go版本为Go应用设置相应的GODEBUG设置。请注意,它不是当前编译的Go版本。根据go.mod中的Go版本号。允许在主包源代码中使用以下形式的一行或多行覆盖特定的默认GODEBUG设置://go:debug=。go/build、golist、goversion-m等配套工具链的使用会同步修改,确保可以显式查看GODEBUG设置。在兼容性指南中记录这些承诺以及如何配置它们以使用GODEBUG。一个更具体的案例其实类似于现有的GODEBUG。例如Go1.20引入了一个新的GODEBUGzipinsecurepath。将遵循以下流程规范:Go1.20中的默认值为1,以保留旧行为并允许不安全路径。Go1.21可能会将默认值更改为0以开始拒绝archive/zip中的不安全路径。如果是这样,并且Go1.21也实现了这个GODEBUG提议,那么当使用Go1.21编译模块(go.mod)和Go1.20时,不安全路径将继续被允许。只有当这些模块版本更新到Go1.21时,它们才开始拒绝不安全的路径。总结Go近年来越来越重视Go1的兼容性保证,今年将进一步加强。该提案已进入最后阶段,很可能会在最新评论中没有反对意见的情况下被接受。本次提案在兼容性方面会增加GODEBUG的使用,最重要的是会根据go.mod文件中的Go版本对GODEBUG进行调整,这将是一个大的小调整。唯一纠结的同学主要是反映很多Go开发者不知道在修改go.mod文件中的go版本时,会导致GODEBUG发生变化,从而影响程序,会比较晦涩难懂。当年rsc给go.mod加上go版本号的时候,说还没想好用在什么地方。。。只想说这棵树埋的真深。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的Why与设计思维Go语言进阶之旅:进一步深入-深度Go源码推荐阅读Go1。20号更新了两次时间,终于不用背2006-01-0215:04:05了!打脸兄弟们,Go1.20竞技场来了!Go十年,终于想起统一日志库!