Go 不是 Java

举报
Q神 发表于 2023/06/24 15:17:47 2023/06/24
【摘要】 长话短说停止发布有关“Go 中的模式”的内容,它们只不过是移植到 Go 语法的冗长 Java 样板,甚至不使用正确的 Go 习惯用法。人们不断发布“Go 中的模式 - XXXXX”文章。它们甚至不是面向对象的模式,但人们一直按原样发布它们。这些“模式”并不是用 Go 惯用语言编写的。即使它们是,很容易发现,Go 也不是面向对象的语言;它是面向对象的语言。或者是吗?那么什么是面向对象呢?创建 ...

长话短说

停止发布有关“Go 中的模式”的内容,它们只不过是移植到 Go 语法的冗长 Java 样板,甚至不使用正确的 Go 习惯用法。

人们不断发布“Go 中的模式 - XXXXX”文章。

  1. 它们甚至不是面向对象的模式,但人们一直按原样发布它们。
  2. 这些“模式”并不是用 Go 惯用语言编写的。
  3. 即使它们是,很容易发现,Go 也不是面向对象的语言;它是面向对象的语言。或者是吗?

那么什么是面向对象呢?

创建 Go 语法时做出的语言决策是对 C++ 浪费的冗长样板文件的直接反应(讽刺的是,在 Java 中继承了相同的东西,但更糟糕的是,至少所有额外的样板文件现在都在一个文件中) )。

面向对象编程实际上不是关于对象,而是关于消息传递。

我对“对象”这个词感到遗憾。它让很多人把注意力集中在次要的想法上。真正的问题是消息传递。消息传递是通信机制的抽象。它允许系统的不同部分在彼此不了解的情况下进行交互。这就是对象的力量,也是它们如此有用的原因。

— 1997 年,艾伦·凯 (Alan Kay) 接受《多布博士日记》彼得·塞贝尔 (Peter Seibel) 的采访。

那么为什么C++和Java被称为“面向对象”呢?

我创造了“面向对象”这个术语,我可以告诉你我脑子里没有 C++

— 艾伦·凯,OOPSLA '97

如果您在听到“面向对象”时不应该想到 C++,那么 Java 也不是。特别是因为Java没有“消息传递”。

Java 和 C++ 让你觉得新的想法和旧的想法一样。Java 是自 MS-DOS 以来冲击计算领域最令人苦恼的东西。— 1997 年,艾伦·凯 (Alan Kay) 接受《多布博士日记》彼得·塞贝尔 (Peter Seibel) 的采访。

猜猜看有什么作用?去。特别是goroutine,它们受到 Erlang进程的启发。

按照该术语创建者的定义,这是否使得 Go 成为“面向对象”?其本身并非如此,但它确实使其比 C++ 或 Java 更加“面向对象”。尤其是他们否认这两种语言都符合他们最初的概念标准。

如果你考虑一下他后来对这个定义所做的其他陈述,那就更重要了。让我们寻找更多证据来支持我的论点。

那么C++和Java应该叫什么呢?嗯,这对于另一篇或多篇文章来说已经足够了,但考虑到该术语的发明者所说的,其他任何东西都会是一个更好的术语。

我个人认为“面向类类型”在语义上更合适,因为 Alan Kay 更关注术语“类”,甚至少于“对象”,而 C++ 和 Java 首先都是关于类和类型系统,而对象只是一个副作用向它们实例化类。

那么,艾伦·凯 (Alan Kay) 认为用他自己的话说,“面向对象”语言的定义是什么?

OOP 对我来说仅意味着消息传递本地保留和保护以及状态过程的隐藏,以及所有事物的极端后期绑定

— Alan Kay 摘自 2003 年 7 月 23 日发给 Stefan Ram 的电子邮件

在 Go 中你会怎么做?

将每个结构体字段设置为非导出(名称以小写字母开头),这对package privateJava 迷来说,除了处理隐藏数据的导出函数之外什么都没有。让每个函数都接受一个Interface并且不返回任何内容,但struct实现了一个导出的Interface

拼写出来:

  • 仅消息传递:仅导出函数,并且Interface它只是function公共签名的集合,因此您可以有效地将函数或函数集合传递给函数,从而传递消息传递
  • 状态进程的本地保留、保护和隐藏:非导出struct字段满足包级别之外的所有这些标准,package == local
  • 所有事物的极端后期绑定:从实际角度来看,这是一个棘手的问题。

    艾伦·凯承认困难是促使这一要求的原因。“ (我并不反对类型,但我不知道有任何类型系统不是完全痛苦的,所以我仍然喜欢动态类型。)” - 摘自 2003-07-23 给 Stefan Ram 的电子邮件

    Go 语言的最初设计允许Interface通过“鸭子类型”推断实现,这是为了消除与静态类型相关的很多麻烦,大部分是样板文件。

    Go是静态类型安全语言;它不专门进行后期绑定,更不用说极端后期绑定了。对于非平凡大小的代码库,您很快就会发现,无论您通过极端后期绑定获得什么,您都会因为没有编译时检查而损失更多。在 Go 中,有多种方法可以进行后期绑定,但是您必须在所有这些地方使用interface{}或与泛型一起any使用,这会让您很快质疑自己的选择。鸭子类型和现在的泛型是两个极端之间的一个不错的折衷方案。

那么,根据该术语创始人的澄清声明,哪些语言是“面向对象”的呢?

我最熟悉的一个是Erlang ,因为我已经用它编写了现实世界的生产应用程序。我之所以学习它,是因为它是为需要 9 个“9”正常运行时间的现实场景而创建的。我学习它是因为我需要创建东西,它需要类似的正常运行时间。我确信评论中会提到其他函数式语言,但这是我在已部署的商业生产环境中拥有第一手经验的唯一一种函数式语言。

*为什么我现在不是 Erlang main 了?*

对于不需要使其独特的功能的事物来说,这并不是一种实用的语言。很少有项目需要 Erlang 提供的极端正常运行时间和大规模并发性,但需要考虑成本。至少另一篇文章值得花费。

作为曾经的Java主力,尴尬了……

你所推动的甚至不是“面向对象”,而是对它的一种歪曲,以至于它甚至无法被识别。

当你的实现甚至没有开始使用 Go 习惯用法并忽略 Go 特定的东西时,尤其令人尴尬的是,这些东西是专门为了做你认为你正在“提供信息并展示你的能力的事情而实现的,而你只是暴露了相反的情况并且向最弱势群体、那些比你了解更少的人传播错误信息。同时向法学硕士提供更多错误信息。

请停止在 Go 上推行“面向对象模式实现”,就像你在告诉那些在过去 10 多年里一直使用 Go 的无知和不成熟的大众并拯救他们一样。很尴尬,我自己作为一个前Java主播这么说。您想知道为什么 Java 程序员名声不佳吗?

是什么引发了发表这篇文章的冲动。

让我们以有史以来最受欢迎的四人帮模式为例。尤其是对于 Java 忠实用户。当介绍“可重用设计模式”时,大多数人都会首先顿悟;可能是因为它最容易理解和滥用。辛格尔顿

只是为了确保我的观点不会被误解,这与 Singleton 无关

我的观点是关于那些将 Java 移植到 Go 语法中的糟糕想法的文章。它们仍然是 Java 示例。

对于这个例子:

让我们忽略这样一个事实:当它第一次被记录时,它是一个可怕的反模式,因为根据定义,它是全局状态和 #1 goto Java 模式。“单身人士被认为是有害的”已经存在了几十年。看看我在那里做了什么;转到,单例

我们还可以忽略这样一个事实:在 JVM 中,您甚至无法正确实现 Single,因为按照设计,JVM 无法保证创建一个类的唯一一个实例。这里给所有自称 Java 专家的人一个提示,他们将就我的错误发表评论;多个类加载器。

如果您看到有人发布“Go 中的模式 - 单例”,请首先查看他们发布的实现;sync.Once()如果您在代码中没有看到任何地方,请让他们在注释中添加它!

这就是你应该谴责他们的,他们宣扬错误信息。发表一篇关于他们几乎不了解基础知识的“教学”文章的狂妄自大。对于那些知道得比他们还少的人来说,这是一种恶意伤害。

互联网的其余部分已经证明了所有其他观点,这就是为什么我在开头加上“让我们忽略......”警告。

我试图研究本文中的所有内容以确保事实的准确性,但我相信互联网会告诉我他们对此的看法。如果有任何事实不准确的地方,并且您想在评论中指出,请提供来源,我会纠正它们。否则,不要浪费其他人的时间。如果它足够重要,需要纠正,那么像我对报价和技术规格所做的那样,站点来源也足够重要。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。