Go 的别名提议和我对谷歌控制 Go 的所有担忧

Go 的别名提议和我对谷歌控制 Go 的所有担忧

原文:https://medium.com/hackernoon/gos-alias-proposal-and-all-my-concerns-of-google-controlling-go-a39f6c6046aa

语言设计回音室

TL;DR:别名提议是一个错误的解决方案,它解决了一个更大的问题,即 Go 实现其既定目标的能力

别名提议是一个语言特性,可能会被添加到下一个版本的 Go 中。如果你有时间,你可以阅读 github 上的设计文档或者一些 Tylenol,你可以阅读 github 关于提案本身的讨论。还有一个有趣的邮件列表讨论有更多的上下文。

为了解释别名提议,让我们假设您有一个客户包,它被一个购物车包用来购物。

稍后,您决定将项目移动到它们自己的包中,因此您将代码更改为 move Item。

如果你是一个小代码库,这很好,但是如果你是谷歌,那么你就有问题了,因为其他应用程序的代码不能编译,因为当他们使用客户端时,他们希望传入一个客户。但您的客户端现在接受了 item.Item。他们可以继续使用您的旧客户端,但他们也不会获得错误修复。根据别名提议,您的新客户包将包含一个别名。

现在旧代码仍然编译,因为客户。项目仍然存在。新代码可以创建项目。项目直接,可能与新项目内的额外功能。项目,并使用新的购物车。客户端 API。

目标是当每个人都更新了 customer 之后,您最终删除别名定义。项目到项目.项目

这是个现实问题吗?

软件开发不仅仅是语言语法。它存在于一个更大的工具系统中。事实上,Go 对这种年轻语言的强大工具支持有助于它的采用。将问题推给工具还有一个额外的好处,那就是不需要向后兼容某个后来可能是错误的特性。它也不会通过强制语言特性将一家公司的需求(谷歌决定使用大型整体存储库的缺陷)强加给其他公司。

谷歌创建别名提案的具体问题可以通过谷歌运行的工具来解决,以编译器安全的方式进行这种大规模转换。我认为声称谷歌太大,工具无法工作是不公平的。尽管如此,在这篇文章的其余部分,我们将假设这是一个真正的问题,需要一个语言层面的解决方案。

岔开话题:谷歌控件 go?

有人曾经指责我声称谷歌控件 Go。不,它属于贡献者。Go 不仅仅是源代码,而是它发布的内容。从这个角度来看,https://golang.org 说围棋是什么,围棋就是什么。

< whois golang.org
...
Registrant Organization: Google Inc.
...

谷歌明确拥有 golang.org,因此控制着 Go 的发布。

你说的是控制,不是拥有!

Go 语言定义和语法是由 Russ Cox 公开拥有的,但是这种所有权是被剥夺的。如果他不同意另一个核心团队成员的意见,会发生什么还不清楚(我希望这个决定是不作为),但在公开场合,他有最终决定权。尽管如此,说谷歌员工控制了围棋的语言是不公平的,因为谷歌控制了围棋。他们有自己的大脑!

相反,这是谷歌编写代码的方式,它似乎指导了 Go 的语言和新功能。这不一定是件坏事!他们都是聪明人,往往能写出好的代码,所以模仿起来也不错。

有限球体控制的最大问题是气泡效应。这个领域内的用户问题变成了一个回声室,放大了他们对里面的人的重要性。在这个泡泡中,正确编写代码的文化成为了 Go 语言理论所基于的公理。

反例示例:供应商特性

当 Go 1.0 发布时,人们抱怨它没有什么新东西。不创新!Go 1.0 中所有重要的东西:轻线程、通道、无异常等等。它们都存在于以前的语言中。创新并不总是一件好事:看看时尚。

Is fashion better when it innovates?

只要把简单的部分做好,我们就能创造出伟大的语言。我很高兴没有尝试新事物,我对围棋很满意。然后,Go 发布了供应商特性……在 Google 使用 Go 的领域内,管理依赖关系显然不是问题,因为当工程师在邮件列表上提出这个问题时,典型的反应是处理它。这可能是以下情况的副作用:

  • 当 Go 1.0 发布时,没有外部依赖的问题,因为在 else 上没有 Go 代码。
  • Google 倾向于使用整体存储库,依赖关系只是同一个存储库中的代码

我想我们抱怨得够多了,因为最终 Go 发布了一个解决方案 而且是创新的!据我所知,劫持依赖于源文件目录的绝对导入路径的特性,允许两个源文件对相同的绝对导入路径有不同的想法是 Go 中唯一的原创特性。难怪我不喜欢这个功能!它可以创建字面上不可调用的公共 API,实际上不是单例的单例,这是一个让库作者望尘莫及的半个特性。它给代码作者认为很直观的东西带来了惊喜,并且有多个陷阱。

在为 厂商创新 辩护之前,想想为什么其他语言没有走这条路。我认为有三种解释:

  • 围棋与众不同,它只对围棋有意义
  • 为其他语言考虑解决方案的人没有聪明到想到/vendor 文件夹解决方案
  • /vendor 文件夹实际上不是一个好主意

我对这个特性如此糟糕的直觉是,它并不是来自谷歌的真正需求。泡泡不仅创造了泡泡认为是好主意的特性,还拙劣地实现了泡泡不完全理解的特性。

这就是为什么我对包管理团队提出一个 Go 包管理的解决方案感到兴奋。多年以后,很明显一个伟大的包管理解决方案不能来自谷歌内部。普遍的谚语是需要是发明之母。我想最终的想法会被加入到谚语列表中。

没有人喜欢 dep 的解决方案,但 dep 却是每个人的最爱

如果 Go 在创建/vendor 文件夹之前遵循相同的过程,并授权相同的人考虑类似于 弃用 go get 的解决方案,我们将会有一个看起来非常不同的解决方案。它根本不会创新,而是(就像一套剪裁精良的西装)包含现有解决方案的工作片段。

别名提案、泡沫和不彻底的措施

别名提案解决了 Google 在迁移定义时遇到的一个特殊问题。在一个独立的整体存储库的环境中,这是一个合理的解决方案。我担心的是,在更广泛的 Go 社区中,这只是一种局部措施。我希望有一个完整的解决方案,但是当我们最终得到它时,我们仍然会有部分解决方案。

从提案本身可以看出部分泡沫。该提案讨论了在迁移到新包完成时删除别名的问题。不幸的是,这在开源项目中是不可能的,因为你不可能知道每个人都在使用你的代码。即使在开源社区之外,也有一些私人公司同时维护着大量不使用整体库的 Go 代码库,在这些情况下,也很难知道迁移何时完成。

被忽视的更广泛的问题是 Go 在创建隔离包时遇到的麻烦。Go 的既定目标包括开发被许多团队使用的软件,这些团队之间的协作有限。与这个目标背道而驰的最大问题是包间依赖。包间依赖明显违背了 Go 的有限协调目标。你可以在《围棋箴言》中看到这方面的暗示。

一点点模仿胜过一点点依赖。

我相信别名提议是 Google 特有的折中方案,真正要解决的问题是不必要的包间依赖。Go 的隐式接口实际上解决了这个问题的一部分。例如,假设你有两个包。

这里的问题是商店和购物车之间有一个包依赖关系,这可能需要协调它们。老实说,它也限制了 Store 的功能,因为它不应该只适用于购物车,还应该适用于任何有 Subtotal()的东西。相反,我们可以将 store 写成如下形式。

在这个版本中,存储是一个独立的包。因为它是一个独立的包,别名提议没有实际意义。它可以作为“手推车”存在。购物车,购物。购物车,或商店。Cart”而且只要它实现 Totaller 一切都好。主观上我也觉得这个实现比较好。商店现在可以呈现包含小计()的所有内容,而不仅仅是购物车。值得注意的是,这个流程符合我对 Go 接受接口、返回结构的一般建议。

我们可以把同样的理念带回最初的客户。客户。客户重要吗?客户。购买需要客户。物品,物品。或者它采用一个指向某个具有价格浮动 64 字段的结构的指针?为了价格,我们可以用 setter 和 getter 来包装项目,但是实际上对于结构来说这是不可行的(大多数 Go 代码倾向于主动避免 setter 和 getter)。

我们在接口方面也遇到了类似的问题。例如,以下代码不适用于 store2.go

编辑:一个早期的版本包含了很多不同的代码,没有显示出我想要表达的观点。我道歉,并已更新的例子。

在这里,package app 试图孤立存在,但不能公开 store 可以实现的接口。我们可以让商店直接使用应用程序。Totaller,但是我们创建了一个包依赖关系,这可能是不可取的,并且需要在每个包更新时进行协调。

Go 隐式接口的这些限制实际上通过创建不必要的包间依赖伤害了 Go 的既定目标,这使得并行开发代码库更加困难。这是核心问题,是开源和闭源 Go 社区都有的问题,别名提议是这个问题的子集。

我们可以做得更好

我的直觉告诉我,别名提议只是谷歌特定问题的一半解决方案。我相信同样的人可以创造出一个更通用、更优雅的解决方案,来解决 Go 社区的一系列问题:一个我自己可能不够聪明的解决方案。这个更通用的解决方案将同时对 Go 的既定目标起到更大的推动作用,并完全消除对 alias 提案的需求。

我认为真正的解决方案更接近于 https://github.com/golang/go/issues/8082 的 T4。很遗憾,这个问题几乎立刻就被贴上了 Go 2.0 的标签。具体的提议存在向后兼容性问题,但我相信这些问题可以通过思考解决。尤其是当别名提案这样的事情向新符号和语法这样的大胆想法敞开大门的时候。

我还建议,更通用的解决方案不必涵盖现有别名提案的每一个细节。相反,它只需要覆盖足够的表面区域,使得设计良好的 Go 库(那些遵循最佳实践 API 设计的库)总是留有移植计划。

没有折中的办法

在向后兼容的世界中,不彻底的措施的问题是仍然需要完整的解决方案。当它最终被实现时,所有这些折中的方法都陷入了向后兼容的困境。

No half measures

黑客中午是黑客如何开始他们的下午。我们是 @AMI 家庭的一员。我们现在接受投稿,并乐意讨论广告&赞助机会。

如果你喜欢这个故事,我们推荐你阅读我们的最新科技故事趋势科技故事。直到下一次,不要把世界的现实想当然!


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除