在做新的应用选型时,我们会进行应用编程语言的选择,这时会纠结 Java、PHP、Go...各种,会思考有没有致命的问题,不能用?,可以明确的是,Go 没有非常致命的问题,否则你我他都不会在这里相遇,也不会大火。,难受的点,倒是有不少,今天就由煎鱼和大家一起来看看。,在 Go1.18 以前,在所有社交媒体和调查报告上来看。Go 最难受的莫过于没有泛型,,写一个通用的方法,要不得把入参声明为 interface,要不得写 N 个不同类型的一样代码的函数,代码重复率高。,如下图:,这是 Go1.18 以前最难受的点,现在新版本虽然有了泛型,但现阶段配套标准和开源库还没完全到位,影响还是会继续存在。,在写 Go 程序时,我们经常要用到 slice、map 等基础类型。但有一个比较麻烦的点,就是会涉及到浅拷贝。,一个不注意就会引起 BUG,如下代码:,输出结果是什么?,煎鱼到底是上班了,还是下班了?,结果如下:,实际上在 y := x 时,他拷贝的是指向对象的指针,这个时候 x 和 y 的底层数据其实是一家子,自然一变动 y,x 的煎鱼也就下班了。,同类型的 slice 也有 append 的泄露,以及 len、cap 的不准确问题,是比较折腾人的。,泄露的示例:,有兴趣的可以具体看《Go 切片导致内存泄露,被坑两次了!》的解析。,在 Go 的错误处理中,许多小伙伴的难受的点分两大块。一个是大量重复的 if err != nil 的代码:,另外一块是在异常处理中,Go 现阶段是 panic 和 recover 的模式,内部还包含 throw 的致命性错误抛出,无法拦截,为此我也见过个别事故是因此造成的。,这是一个争议性很大的板块。,我们强行将一段 Go 程序的变量值赋为 nil,并进行 nil 与 nil 的判断。,代码如下:,输出的结果是什么。是 false,还是 true,又或是抛出异常?,输出结果是 fasle,nil 可不 100% 等于 nil。,这与 interface 的内部数据结构有关,是在编程时要注意的一个细节,具体可详见《Go 面试题:Go interface 的一个 “坑” 及原理分析》的解析。,Go 非常简洁,垃圾回收唯一的可调节的是 GC 频率,可以通过 GOGC 变量设置初始垃圾收集器的目标百分比值。,简单来讲就是,GOGC 的值设置的越大,GC 的频率越低,但每次最终所触发到 GC 的堆内存也会更大。,然后就没别的方式可以优化垃圾回收器本身了,以至于当年我还被人拿 Java 来吐槽过一遍,说 Go 肯定有。,压轴的难受点,莫过于 Go 的依赖管理。先是从 GOPATH 时代,开源后一路水土不服,后面 rsc 直接下场支棱起来硬推。,到 2022 年,目前 Go modules 还是会存在一些让人难受的点。甚至曹大总结了 《Go mod 七宗罪》,不少我在工作中也遇到和替别人解决过,非常的精辟。,引用曹大文章中的 7 点:,熟悉掌握 Go 的一个表现,那就是精通 Go modules,不然项目都运行的不顺利。,今天我们围绕 Go 的难受场景进行了分析和讲解,本文涉及的分别是:泛型、浅拷贝和泄露、错误处理、nil 接口不是 nil、垃圾回收、依赖管理。,其中不少是常见的,也有的是有意而为之(例如:垃圾回收)。从大家的角度来看,你觉得 Go 比较难受的点还有哪些呢?
© 版权声明
文章版权归作者所有,未经允许请勿转载。