大家好,我是建宇。在进行新的应用程序选择时,我们将选择一种应用程序编程语言。这时候我们就会纠结于Java、PHP、Go等,会思考是否存在不能使用的致命问题?明确的是,围棋没有一个很致命的问题,否则你我他也不会在这里相遇,也就不会火起来。有不少不爽的地方,今天就和大家一起看看吧。Go1.18之前所有社交媒体和调查报告中的不适点泛型。Go最难受的地方就是没有泛型。写一个通用的方法,必须将入参声明为接口,或者用同样的代码写N个不同类型的函数,代码重复率高。如下图所示:这是Go1.18之前最难受的一点。新版本虽然有泛型,但现阶段配套标准和开源库还没有完全到位,影响还会继续存在。浅拷贝和泄漏在编写Go程序时,我们经常会用到slice和map等基本类型。但是还有一个比较麻烦的点,就是涉及到浅拷贝。一不留神就会造成BUG,如下代码:typeTstruct{AstringB[]string}funcmain(){x:=T{"Friedfish",[]string{"去上班"}}y:=xy.A="咸鱼"y.B[0]="下班"fmt.Println(x)fmt.Println(y)}的输出是什么?炸鱼是上班还是下班?结果如下:{Friedfish[Offwork]}{Saltedfish[Offwork]}其实当y:=x时,他复制的是指向对象的指针。这时候x和y的底层数据其实是一家人,自然要改y,x的炸鱼就下班了。同类型的slice也有append的泄露,len和cap的不准确,比较麻烦。泄露的例子:vara[]intfuncf(b[]int)[]int{a=b[:2]returna}funcmain(){...}有兴趣的可以看的分析。错误处理在Go的错误处理中,很多小伙伴的不爽点分为两部分。一个是很多重复的iferr!=nil代码:funcmain(){x,err:=foo()iferr!=nil{//handleerror}y,err:=foo()iferr!=nil{//处理错误}z,err:=foo()iferr!=nil{//处理错误}s,err:=foo()iferr!=nil{//处理错误}}另一块异常在处理过程中,Go目前处于panic和recover模式,里面还包含throwfatalerrors,无法拦截。为此,我也看到过个别由此引发的事故。这是一个非常有争议的领域。nil接口不是nil。我们强行把一个Go程序的变量值赋给nil,在nil和nil之间做判断。代码如下:funcmain(){varvinterface{}v=(*int)(nil)fmt.Println(v==nil)的输出是什么}。是假的,还是真的,还是抛出异常?输出是fasle,nil不是100%等于nil。这与接口内部数据结构有关,是编程时应该注意的一个细节。具体可以参考《Go 面试题:Go interface 的一个 “坑” 及原理分析》的分析。垃圾收集Go非常简单,唯一可调整的垃圾收集是GC频率,可以通过GOGC变量设置初始垃圾收集器的目标百分比值。$GOGC=100eddycjy简单来说,GOGC的值设置的越大,GC的频率越低,但是每次GC触发的堆内存会越大。然后就没办法优化垃圾收集器本身了,以至于当年我什至被吐槽过Java,说Go必须有。依赖管理压轴的难受点是Go的依赖管理。先是从GOPATH时代开始,开源之后,一路风雨飘摇,然后rsc直奔最后,硬推。到2022年,当前的Go模块仍然会有一些不舒服的地方。曹达还总结了《Go mod 七宗罪》,其中很多都是我在工作中遇到并为别人解决的,非常精辟。下面引用7点:Go命令的副作用:所有的gobuild,golist,gotest都会或多或少的拉墙外的资源,会很慢。不存在的semver规范:gomod的设计是希望大家在发布软件库时必须遵守标准,比如在小版本中保持兼容性。但这是非常理想化的,现实是人们往往不遵守。无法处理库删除:您已经拉取了已发布的软件库。但是发布者还是可以删的,受伤的还是自己。goproxy的实现不统一:作者A、作者B、作者C写的几套goproxy内部逻辑并不完全一致,很郁闷。goget获取的lib版本在gobuild时被修改。版本信息扩散:导入路径包含版本号v1、v2等信息,一旦修改,必须大面积替换。go.sum合并冲突:多人维护大型项目,导致冲突频繁。熟悉Go的表现之一就是要精通Go模块,否则项目不会顺利运行。总结今天我们分析和解释了围棋的难受场景。本文涉及:泛型、浅拷贝和泄漏、错误处理、nil接口不为nil、垃圾回收、依赖管理。其中许多是常见的,有些是有意的(例如:垃圾收集)。从大家的角度来看,大家觉得围棋比较难受的是什么?欢迎大家在评论区留言,一起交流。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。推荐阅读这道围棋题你能答对吗?80%以上的人都答错了……Go的返回值命名还有必要吗?引用golang有致命问题吗?去修改七大罪
