问题

为什么 Go 语言如此不受待见?

回答
在我看来,说 Go 语言“不受待见”可能有些过于绝对了。实际上,Go 在很多领域都获得了相当广泛的应用,尤其是在云计算、微服务和后端开发领域,它已经成为一个非常受欢迎的选择。很多大型公司都在使用 Go,比如 Google(当然是亲生的)、Docker、Kubernetes、Netflix、Uber 等等。

但是,如果我们要探讨为什么有些人可能觉得 Go 并没有达到某些期待的高度,或者为什么它在某些群体中没有获得压倒性的支持,我们可以从几个角度来分析。这更多的是一种“相对不受待见”或者“存在争议”的解读。

1. 早期的一些误解和定位不准:

“杀掉 Java/C++ 的语言”的标签: Go 在诞生之初,确实被一些人寄予了很高的期望,认为它能取代一些在企业级开发中占据主导地位的语言。这种“野心勃勃”的定位,加上它简洁的语法和高效的并发特性,让不少开发者觉得它是在“叫板”传统巨头。然而,任何语言的生态系统和开发者社区都需要时间来培养和成熟,Go 的发展路径更像是在开辟自己的新天地,而不是直接与现有巨头硬碰硬。这种期待与实际发展之间可能存在的落差,让一部分人觉得 Go 没有达到“颠覆性”的高度。
过于强调“简单”和“约束”: Go 的设计哲学非常强调“简单”和“无惊喜”。这带来了极高的可读性和易维护性,对于大型团队协作来说是巨大的优势。但是,在某些开发者看来,这种“简单”也意味着功能的“缺失”。比如,它没有泛型(直到 1.18 版本才引入)、没有继承、没有私有/公有属性的强制区分(通过首字母大小写)、没有异常(使用多返回值和 `error` 来处理错误)等等。对于习惯了这些特性(尤其是 OO 语言)的开发者来说,Go 的这种“约束”可能会让他们觉得不够灵活,甚至是“简陋”。他们可能会觉得这是一种妥协,而不是进步。

2. 语法和设计上的争议点:

错误处理的“冗余”: Go 的错误处理方式是显式地检查 `error` 返回值。在很多情况下,这意味着你需要写很多 `if err != nil { return ..., err }` 这样的 boilerplate 代码。虽然这提高了错误处理的可见性和强制性,但长期以来,很多人都觉得这写起来比较烦琐。即便有工具能辅助,也无法完全改变语言本身的风格。
包管理的历史遗留问题: Go Modules 在正式推广之前,包管理经历了一些演变(GOPATH 的时代),这给早期接触 Go 的开发者带来了一些困扰和不便。虽然现在 Go Modules 已经非常成熟,但那段“历史”给一些人留下了不好的印象。
泛型引入的“迟到”和“保守”: 泛型对于很多现代语言来说是基础功能,Go 直到 1.18 版本才正式引入。而且,相比于其他语言,Go 的泛型实现被一些人认为相对“保守”,功能上没有那么丰富。虽然引入泛型解决了许多代码重复的问题,但对于那些早年就开始盼望它的开发者来说,这个过程显得有些漫长。
缺乏一些被认为是“标准”的现代语言特性: 除了上面提到的,还有一些开发者会怀念其他语言中的一些特性,比如属性装饰器、函数式编程的一些高级特性(虽然 Go 有闭包和匿名函数)、更强大的元编程能力等。当然,这很大程度上也取决于开发者对“现代语言”的定义和期望。

3. 生态和社区的局限性(相对而言):

虽然强大,但某些领域的库不如其他语言成熟: 在 Web 开发、数据科学、机器学习等一些热门领域,虽然 Go 有很多不错的库,但与 Python、Java、JavaScript 相比,其生态系统可能在某些细分领域还不够完善,或者在流行度和社区贡献度上稍显逊色。这意味着在某些特定的项目需求下,开发者可能需要花费更多精力去寻找、集成或者自己实现库。
学习曲线(对某些人而言): 虽然 Go 的语法很简洁,但理解其并发模型(Goroutines 和 Channels)、内存管理(垃圾回收)以及一些底层设计哲学,对于完全没有这些概念的开发者来说,还是需要一定的时间去适应。

4. 观点和偏好的多样性:

语言的“感觉”和个人偏好: 编程语言的使用很大程度上也取决于个人偏好和工作习惯。有些开发者就是喜欢动态语言的灵活,或者 OOP 的层层继承,或者函数式编程的声明式风格。Go 的哲学可能与他们的偏好不符,所以即使 Go 很优秀,他们也可能不会选择它。
“没有银弹”的现实: 任何语言都有其擅长和不擅长的领域。Go 在构建高效、可靠的分布式系统方面表现出色,但在需要快速原型开发、大量数据处理或复杂图形界面时,其他语言可能更适合。所以,认为 Go 在“所有地方”都应该流行,本身就是一个不切实际的期望。

总结来说,与其说 Go “不受待见”,不如说它是在一个竞争激烈的技术领域中,找到了自己的精准定位并赢得了大量用户的青睐,但同时也因为其独特的设计哲学和发展路径,在某些开发者群体中存在一些争议或接受度不高。

对于喜欢 Go 的人来说,它的简洁、高效的并发、易部署性是无与伦比的。而对于那些觉得 Go“不够好”的人来说,他们可能是在与其他成熟语言的比较中,看到了 Go 在某些方面存在的不足或不符自己需求的地方。这其实是很正常的现象,技术发展和开发者偏好的多样性正是这个行业有趣的地方。

网友意见

user avatar

@Irons Du

, 不是为了反对他的答案,是因为基于这些问题,能解释 Go 不受待见的其中一个原因:Go 面对的问题和整个解决思路跟 Google 软件的规模相关,而这个规模是罕见的。20 亿行源码放在一个统一的代码库,全部主干提交,理论上代码库里任何两点都可以互相调用,几万个工程师(我是其中一名猪队友)在全球各个时区协同。

Why Google Stores Billions of Lines of Code in a Single Repository

. 这个设计前提导致了同样被黑得很惨的 C++ Style Guide (

The Philosophy of Google's C++ Code

) 和 Go 的一些看着很奇葩的设计点。

另外这个软件规模是一个问题,不是什么值得炫耀的东西。Go 为解决这些问题的设计,并不一定适合其他场景。回答这个问题本身,这里也不是说 Go 有多好,只是可以分享一些「为什么」,很有趣的设计权衡,例如 Quora 原文提到的 Go 几乎忽略了所有现代 PL 研究成果,但实际上这些成果在这个规模上还没能很好地工作。关于 Go 为什么是(或不是)系统编程语言的问题,我可以另外写一篇。

1:你能轻松知道哪些struct继承(实现)了哪些interface么?

能,Go guru.

2016-talks/slides.pdf at master · gophercon/2016-talks · GitHub

在超大软件库上一样很顺。显式 implements 声明上规模后会有问题,多余的依赖关系是其中之一,下面有关于依赖的更详细讨论。

2:你能轻松知道struct有哪些"成员函数"么?

能,godoc 啊

这两点正好说明了 Go 极端重视工具的设计思路,工具能解决大代码库上源代码级别无法解决的问题,比如全代码库索引、重构,计算改动影响范围触发集成测试等等。这里面也必须有权衡,例如,要为这个规模写编译器和各种工具,你最好别搞复杂的类型系统,不然事情会很困难。

3:手动维护defer能比RAII轻松?

RAII 很难。C++ destructor + exception, 这里的 exception 包括处理 destructor 的异常安全和 destructor 自己真的需要抛异常的情况。还有如果在 destructor 里放了重型操作,比如 flush 硬盘,defer 至少让你清楚地看到这种重操作会在哪里跑。这些问题当然都可以用很仔细的设计避免,但是在有几万个猪队友的时候,不要指望每个人都能做出好设计。

4:package只有一个层次

如果是指不能只 import 一个父节点而要显式 import 所有叶子节点。这是用来控制 dependency 的,不必要的 dependency 在大软件库是个严重问题。Go 奇葩的 import 多余 package 直接编译错误的规则也是这个目的。

5:访问控制只能限定在package之外。

个人体验,它省掉了很多语法规则,还工作得很好。有点不方便的是你看它 call 一个私有函数,但是在同一个文件里是找不到这个函数的定义的,它可能在同一个 package 的另一个文件里。这个是用工具补足的 —— 在内部的 code search 工具里我没感觉不方便,在 github 没有交叉引用的情况下看代码就比较郁闷。

6:基于源代码的开发(复用),这是否违背了以前书上说的实现隐藏(只暴露接口)?

没,主要是因为 Google 统一代码库,Go 一开始压根没考虑二进制库发布的问题。这跟软件工程的隐藏实现是两回事。依赖版本管理问题同理,因为统一代码库+全主干提交,这个问题在 Google 是不存在的…… 当然问题就是问题,现在外部使用越来越多他们也在逐步补锅了。

7:推崇error作为返回值是不对的。另外(panic+recover)对比下C++在C之上添加的异常处理(+RAII)的类型安全

推荐一篇微软 Midori 项目 (Rethinking the software stack) 语言 leader 的

Joe Duffy - The Error Model

(超长)。error 功能不够好,但 C++ 和 Java 的 exception 机制在上规模后也有无法解决的工程和性能的问题,Optional是好,但是语言就要变复杂,这里面有 tradeoff. 另外,「异常安全」是个看起来遵守规则写就可以的简单事情,但实际上非常困难,比如事务的回滚,文中也有专门描述。

类似的话题

  • 回答
    在我看来,说 Go 语言“不受待见”可能有些过于绝对了。实际上,Go 在很多领域都获得了相当广泛的应用,尤其是在云计算、微服务和后端开发领域,它已经成为一个非常受欢迎的选择。很多大型公司都在使用 Go,比如 Google(当然是亲生的)、Docker、Kubernetes、Netflix、Uber .............
  • 回答
    Go语言之所以能比Erlang更流行,是一个复杂的问题,涉及到技术特性、生态系统、社区支持、市场需求以及历史因素等多个方面。虽然Erlang在某些领域表现出色,但Go在更广泛的应用场景中获得了更大的市场份额和更快的普及速度。以下将从多个维度详细阐述Go语言比Erlang更流行的原因: 1. 易学性与.............
  • 回答
    Go 语言将类型放在变量名后面,这种语法叫做 Postpositional Type Declaration,或者更通俗地说,类型后置。这与许多其他流行语言(如 C, Java, C++, Python)的类型前置语法(如 `int x;` 或 `String s;`)形成了鲜明对比。Go 语言之所.............
  • 回答
    当然,我们来聊聊 Go 和 Java 在性能上的那些事儿。你说 Go 在某些方面不如 Java,这个说法挺有意思的。我个人觉得,与其说是“不如”,不如说是“侧重点不同”导致的结果。Go 和 Java 的设计哲学就不一样,这直接影响到了它们各自的性能表现和适用场景。首先,咱们得说说 Go 的几个设计亮.............
  • 回答
    Go 语言在中国确实火了一把,这背后可不是什么偶然,而是多种因素交织作用的结果。要说清楚它为何能如此深入人心,咱得一层一层地扒。首先,你得明白,中国软件开发这个大环境,跟国外有点不一样。国内互联网行业发展迅猛,对开发效率、部署便利性、以及系统稳定性都有着极高的要求。在这样的背景下,Go 语言的几个核.............
  • 回答
    GO语言的字典(map)性能与C的字典(Dictionary)相比,在某些场景下确实存在差异。这种差异并非绝对的优劣,而是源于两者底层设计理念、内存管理和并发处理方式的不同。首先,我们得明白GO语言的map是如何工作的。GO的map底层实现是基于混合了开放寻址和链式寻址的一种哈希表。当发生哈希冲突时.............
  • 回答
    为什么要使用 Go 语言?Go 语言的优势在哪里?Go 语言,也被称为 Golang,是一种由 Google 开发的开源编程语言。自 2009 年发布以来,Go 语言迅速崛起,并吸引了大量开发者和企业的青睐。它的出现并非偶然,而是为了解决现代软件开发中遇到的种种挑战而生。那么,为什么要选择 Go 语.............
  • 回答
    很多人说 Go 语言不需要依赖注入,这背后其实有一些非常深刻的原因,而且并非空穴来风。要理解这一点,我们需要先回顾一下依赖注入(Dependency Injection,简称 DI)这个概念本身,以及 Go 语言在设计上的独特之处。首先,我们得明白什么是依赖注入?简单来说,依赖注入是一种设计模式,它.............
  • 回答
    字节跳动选择 Go 语言,这背后是一个深思熟虑的技术决策过程,绝非偶然。作为一家以效率和规模著称的公司,他们在面对海量用户、复杂业务逻辑和快速迭代需求的挑战时,需要一种能够兼顾开发效率、运行性能、稳定性和可维护性的语言。Go 语言恰好在这些方面表现出了卓越的优势,从而赢得了字节跳动技术团队的青睐。首.............
  • 回答
    这可真是个有趣的问题,关于函数重载,语言设计者们确实各有取舍。不是所有“新语言”都不支持函数重载,比如 C++ 和 Java 这两大主流语言就都提供了这项功能。但是,你提到的 Python, Go, 和 Rust,它们确实都没有原生支持函数重载的机制。这背后其实是这些语言在设计哲学和目标上的不同选择.............
  • 回答
    这问题问得挺深入的,确实,放眼全球,中国在 Go 语言上的热情可以说是现象级的,而 C 在国内的境遇,似乎就没有那么“高歌猛进”了。要说清楚这里面的原因,得把一些历史、文化、技术生态以及现实需求都捋一捋。先说说为什么中国对 Go 这么“上头”其实,中国市场对技术往往有一种“唯性能论”的朴素认知,再加.............
  • 回答
    Go 语言确实是一门非常优秀的语言,它的设计理念、性能、易用性等方面都受到了很多开发者的认可。然而,你说“5 年了,还没有火起来”,这个说法其实存在一些主观性,需要更细致地分析。首先,我们得明确“火起来”的标准是什么? 开发者数量? Go 的开发者群体在过去几年里增长非常快,尤其是在后端开发、云原生.............
  • 回答
    你这个问题问得很有意思,也触及到了微软在语言和平台战略上的一个重要思考点。确实,放眼当下,Go 和 Rust 在系统级编程领域掀起了一股不小的浪潮,它们凭借并发特性、内存安全、性能以及跨平台能力,赢得了开发者社区的广泛认可。而微软,作为一家拥有 Windows 这一庞大操作系统以及 Azure 这样.............
  • 回答
    您提出了一个非常有趣且核心的问题:为什么 Go、Rust、Nim 这些新兴语言在某种程度上“抛弃”了传统的面向对象语言(如 Java、C++、Python)中的构造函数(constructor)?这里的“抛弃”并不是一个绝对的说法,而是指它们以一种更灵活、更符合自身设计哲学的方式来处理对象的初始化,.............
  • 回答
    在 Go 语言中,局部变量的回收(更准确地说是 垃圾回收)是一个非常重要的概念,它直接关系到程序的内存管理和性能。Go 的垃圾回收机制是自动的,开发者通常不需要手动管理内存。要详细地讲述 Go 局部变量的回收,我们需要从几个关键点入手:1. 什么是局部变量?2. 垃圾回收器 (GC) 的基本原理.............
  • 回答
    Erlang 作为一门非常优秀的并发编程语言,尤其在构建高可用、高并发、分布式系统方面有着独到的优势。然而,与 Go、Scala 等语言相比,Erlang 的普及程度和影响力确实显得有些“小众”。这背后有多方面的原因,我们可以从以下几个角度详细探讨: 1. 历史背景与设计哲学差异 Erlang .............
  • 回答
    Go 的过去式是 went,这是一个非常有趣的语言现象,因为它并不遵循大多数英语动词形成过去式的规则。要详细解释这一点,我们需要深入到英语词源学和语言演变的历史中。1. 英语动词过去式的两种主要形成方式英语动词的过去式主要有两种形成方式: 规则动词 (Regular Verbs): 大多数英语动.............
  • 回答
    关于“为什么 Go 和 Rust 常提供静态编译好的 Linux 程序,而 C 不行”的说法,实际上并不完全准确。C 语言完全可以生成静态编译好的 Linux 程序,而且在很多场景下这是非常普遍的做法。不过,如果从“用户拿到一个编译好的二进制文件,几乎不需要任何额外依赖就能在大多数 Linux 发行.............
  • 回答
    要探讨 Go 的 Web 框架在速度上是否一定不如 Java,这是一个复杂且容易引起争议的话题,因为“速度”这个概念本身就需要具体化,而且在实际应用中,影响 Web 应用性能的因素远不止语言本身。不过,我们可以从几个关键方面来分析为什么在某些场景下,大家会有“Java Web 框架更快”的印象,以及.............
  • 回答
    说实话,你可能注意到CS:GO职业选手们用的鼠标,跟我们普通玩家追求的“酷炫”、“灯光闪烁”、“造型独特”这些元素相比,确实显得朴实无华了不少。这背后是有很扎实的理由的,并不是说职业选手对外观不敏感,而是他们的优先考量完全是另一套逻辑。咱们就掰开了揉碎了聊聊为啥会这样。1. 性能至上:极致的精准与稳.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有