首页 Golang教程为什么 Go 用起来会难受?这 6 个细节你知道吗

为什么 Go 用起来会难受?这 6 个细节你知道吗

运维派隶属马哥教育旗下专业运维社区,是国内成立最早的IT运维技术社区,欢迎关注公众号:yunweipai
领取学习更多免费Linux云计算、Python、Docker、K8s教程关注公众号:马哥linux运维

大家好,在做新的应用选型时,我们会进行应用编程语言的选择,这时会纠结 Java、PHP、Go…各种,会思考有没有致命的问题,不能用?

可以明确的是,Go 没有非常致命的问题,否则你我他都不会在这里相遇,也不会大火。

难受的点,倒是有不少,今天就和大家一起来看看。

难受的点

泛型

在 Go1.18 以前,在所有社交媒体和调查报告上来看。Go 最难受的莫过于没有泛型,

写一个通用的方法,要不得把入参声明为 interface,要不得写 N 个不同类型的一样代码的函数,代码重复率高。

如下图:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图

这是 Go1.18 以前最难受的点,现在新版本虽然有了泛型,但现阶段配套标准和开源库还没完全到位,影响还是会继续存在。

浅拷贝和泄露

在写 Go 程序时,我们经常要用到 slice、map 等基础类型。但有一个比较麻烦的点,就是会涉及到浅拷贝。

一个不注意就会引起 BUG,如下代码:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图1

输出结果是什么?

煎鱼到底是上班了,还是下班了?

结果如下:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图2

实际上在 y := x 时,他拷贝的是指向对象的指针,这个时候 x 和 y 的底层数据其实是一家子,自然一变动 yx 的煎鱼也就下班了。

同类型的 slice 也有 append 的泄露,以及 len、cap 的不准确问题,是比较折腾人的。

泄露的示例:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图3

错误处理

在 Go 的错误处理中,许多小伙伴的难受的点分两大块。一个是大量重复的 if err != nil 的代码:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图4

另外一块是在异常处理中,Go 现阶段是 panic 和 recover 的模式,内部还包含 throw 的致命性错误抛出,无法拦截,为此我也见过个别事故是因此造成的。

这是一个争议性很大的板块。

nil 接口不是 nil

我们强行将一段 Go 程序的变量值赋为 nil,并进行 nil 与 nil 的判断。

代码如下:

为什么 Go 用起来会难受?这 6 个细节你知道吗插图5

输出的结果是什么。是 false,还是 true,又或是抛出异常?

输出结果是 fasle,nil 可不 100% 等于 nil。

这与 interface 的内部数据结构有关,是在编程时要注意的一个细节。

垃圾回收

Go 非常简洁,垃圾回收唯一的可调节的是 GC 频率,可以通过 GOGC 变量设置初始垃圾收集器的目标百分比值。

为什么 Go 用起来会难受?这 6 个细节你知道吗插图6

简单来讲就是,GOGC 的值设置的越大,GC 的频率越低,但每次最终所触发到 GC 的堆内存也会更大。

然后就没别的方式可以优化垃圾回收器本身了,以至于当年我还被人拿 Java 来吐槽过一遍,说 Go 肯定有。

依赖管理

压轴的难受点,莫过于 Go 的依赖管理。先是从 GOPATH 时代,开源后一路水土不服,后面 rsc 直接下场支棱起来硬推。

到 2022 年,目前 Go modules 还是会存在一些让人难受的点。甚至曹大总结了 《Go mod 七宗罪》,不少我在工作中也遇到和替别人解决过,非常的精辟。

引用曹大文章中的 7 点:

  • Go 命令的副作用:所有 go build、go list、go test 多多少少都会拉取到墙外的资源,会很慢。
  • 形同虚设的 semver 规范:go mod 的设计,就是希望大家在软件库发布时都要遵守标准,例如在小版本时,要保持兼容性。但这非常理想化,现实就是经常有人不遵守。
  • 无法应对删库:发布后的软件库,你已经拉取了。但发布者依然可以删除,受伤的还是自己。
  • goproxy 的实现并不统一:作者 A、作者 B、作者 C 写的几套 goproxy 内部逻辑是不完全一致的,很折腾人。
  • go get 到的 lib 版本在 go build 时被修改。
  • 版本信息扩散:导入路径是包含版本号 v1、v2 等信息的,一旦修改,就得大面积替换。
  • go.sum 合并冲突:大型项目上的多人维护,导致频繁冲突。

熟悉掌握 Go 的一个表现,那就是精通 Go modules,不然项目都运行的不顺利。

总结

今天我们围绕 Go 的难受场景进行了分析和讲解,本文涉及的分别是:泛型、浅拷贝和泄露、错误处理、nil 接口不是 nil、垃圾回收、依赖管理。

其中不少是常见的,也有的是有意而为之(例如:垃圾回收)。从大家的角度来看,你觉得 Go 比较难受的点还有哪些呢?

欢迎大家在评论区一起留言和交流。

原文:https://mp.weixin.qq.com/s/8ino57_pYncjotquaCt3dw,侵删!

本文链接:https://www.yunweipai.com/41955.html

网友评论comments

发表回复

您的电子邮箱地址不会被公开。

暂无评论

Copyright © 2012-2022 YUNWEIPAI.COM - 运维派 京ICP备16064699号-6
扫二维码
扫二维码
返回顶部