出泛型后 API 怎么办?Go 开发者要注意了

大家好,我是煎鱼。 前段时间社区里一下子就爆了,主要是各大媒体引用了 Go 语言之父 Rob Pike 所提的《go: don’t change the libraries in 1.18》。 很多社交媒体都做了跟进,认为 Rob Pike 是硬性的反对 Go 泛型的 API 改造! 如果读者只看了标题,有可能会产生一些误解实际上其表达的意思和近期 Go 社区讨论的事项是有关联的,要一起综合来看。 为此,今天煎鱼就和大家一起来理一理,看看 Go 泛型 API 的改造工程,是个怎么一回事? 现状 马上就是 2021.

上帝视角:Go 语言设计失误,缺乏远见?

大家好,我是煎鱼。 前段时间我有一个朋友在某乎上摸鱼时,给我甩来一个主题为《golang 设计者是如何偿还技术债的》链接。 说是让我学习、围观一下社区观点,早日好修成正果,本鱼表示满脸问号。 原回答如下图: 主要是以极短的话语表述 Go 语言的 “泛型、异常、channel、annotation、模块依赖” 的设计是失误的。 说是没有向各种编程语言的 “最佳实践” 各取所需。 那些故事 刚好煎鱼也入门 Go 没几天,偶尔翻过 issues 和 proposal,看了一点点历史事件。 也从我的观点来围观一下 Go 官方这些年为特性挣扎过的那些事。 涉及: 泛型。 错误处理。 依赖管理。 注解。 泛型 为什么 Go 语言这么久都没有泛型,是不是 Go 官方不够 “聪明”,抄作业都不会抄。这显然是不对的。

Go 和 Golang 有什么关系?

大家好,我是煎鱼。 最近天气也冷了,掐指一算是招聘季了,无论是校招、社招、HR、面试官们都蠢蠢欲动。这不,我有一个朋友的 HR 朋友都有起名困难了,一看 Go 语言的工作说明(Job Description),发现各有不同。 如下图: 仔细一看,有叫 Go 的,也有叫 Golang,还有叫 GO 的。好家伙,Go 语言有这么多个别名,甚至某乎都讨论了起来。到底叫什么是正确的? 为此,今天就由煎鱼带大家理一理,了解这背后的关系。 Go 官方定义 从网上的资料来看,大家对 Go 的名字还是比较关注的,对于 Go 团队来讲,仿佛经常被问。例如: “Go 和 Golang 的关系是什么?” “Go、Golang、GO 哪个对?” 甚至在之前探讨 Go2 草案时,也有人开始起 Go2 的名字了,纠结是要叫 “golang2”,还是 “go2lang”:

Go:我有注解,Java:不,你没有!

大家好,我是煎鱼。 作为一位 Go 程序员,你会发现身边的同事大多都拥有其他语言的编写经验。那势必就会遇到一点,要把新学到的知识和以前的知识建立连接。 特殊在于,Go 有些特性是其他语言有,他没有的。最经典的就是 N 位 Java 同学寻找 Go 语言的注解在哪里,总要解释。 为此,今天煎鱼就带大家了解一下 Go 语言的注解的使用和情况。 什么是注解 了解历史 注解(Annotation)最早出现自何处,翻了一圈并没有找到。但可以明确,在注解的使用中,Java 注解最为经典,为了便于理解,因此我们基于 Java 做初步的注解理解。 在 2002 年,JSR-175 提出了 《A Metadata Facility for the Java Programming Language》,也就是为 Java 编程语言提供元数据工具。

为什么 Go 语言把类型放在后面?

大家好,我是煎鱼。 前段时间看到大家在吵一个话题,那就是 Go 语言的类型声明,抠知识抠的非常细了,就是为什么他要放在后面。 示例代码如下: var a []string var b []string 其实在早年 Go 官方估计已经被问烦了,写过一篇《Go’s Declaration Syntax》来具体介绍和说明情况。 为此煎鱼将参考并结合这篇官方资料,带大家一起了解为什么 Go 如此的 “与众不同” ,为什么要把类型放在后面。 类型前置 在业内目前有不少知名语言,也采取的是在声明变量类型时,把类型定义在名字前面。像是 C、C++、C#、Java 等: int x; int x = 100; 基本的格式定义:<data_type> <variable_list>;。

Go 切片导致内存泄露,被坑两次了!

大家好,我是煎鱼。 前段时间在我的 Go 读者群里,有小伙伴们在纠结切片(slice)的问题,我写了这篇《Go 切片这道题,吵了一个下午!》,引起了一拨各种讨论,还是比较欣慰的。 这不,有小伙伴给我提出了新的题材: 提出的是 Go 中很容易踩坑的切片内存泄露问题。作为宠粉的煎鱼肯定不会放过,争取让大家都避开这个 “坑”。 今天这篇文章,就由煎鱼带大家来了解这个问题:Go 切片可能可以怎么泄露法? 切片泄露的可能 在业务代码的编写上,我们经常会接受来自外部的接口数据,再把他插入到对应的数据结构中去,再进行下一步的业务聚合、裁剪、封装、处理。 像在 PHP 语言,常常会放到数组(array)中。在 Go 语言,会放到切片(slice)中。因此在 Go 的切片处理逻辑中,常常会涉及到如下类似的动作。 示例代码如下: var a []int func f(b []int) []int { a = b[:2] return a } func main() { .

Go 什么时候会触发 GC?

大家好,我是煎鱼。 Go 语言作为一门新语言,在早期经常遭到唾弃的就是在垃圾回收(下称:GC)机制中 STW(Stop-The-World)的时间过长。 那么这个时候,我们又会好奇一点,作为 STW 的起始,Go 语言中什么时候才会触发 GC 呢? 今天就由煎鱼带大家一起来学习研讨一轮。 什么是 GC 在计算机科学中,垃圾回收(GC)是一种自动管理内存的机制,垃圾回收器会去尝试回收程序不再使用的对象及其占用的内存。 最早 John McCarthy 在 1959 年左右发明了垃圾回收,以简化 Lisp 中的手动内存管理的机制(来自 @wikipedia)。 为什么要 GC 手动管理内存挺麻烦,管错或者管漏内存也很糟糕,将会直接导致程序不稳定(持续泄露)甚至直接崩溃。 GC 触发场景 GC 触发的场景主要分为两大类,分别是:

Go map 如何缩容?

大家好,我是煎鱼。 前几天看到 Go 圈子的著名股神(不是我…),在归类中简单的提到了 Go 语言中 map 的缩容的描述,这让我对其产生了兴趣,想要来一探究竟。 我们常常喊扩缩容,扩缩容,但社区里都是清一色分析扩容机制,Go 面试官也都是卷 Go 语言 map 的扩容机制… 在 Go 语言中的 map 缩容机制是怎么做的呢,今天就由煎鱼带大家一起研讨围观一轮。 基本分析 在 Go 底层源码 src/runtime/map.go 中,扩缩容的处理方法是 grow 为前缀的方法来处理的。 其中扩缩容涉及到的是插入元素的操作,对应 mapassign 方法:

面试官:为什么 Go 的负载因子是 6.5?

大家好,我是煎鱼。 最近我有一个朋友,在网上看到一个有趣的段子,引发了我一些兴趣。 如下图: 听说是在最后的闲聊、吹水、聊人生、乱扯环节了,不是在技术环节了,所以大家也不用太在意什么技术评估法则(别杠)。 煎鱼作为一名技术号主,看到这里的 6.5,就想给大家挖一挖,这到底是何物,和大家一同学习和增长知识! 6.5 是什么 实际上在 Go 语言中,就存在 6.5 这一概念,与 map 存在直接关系,因此我们需要先了解 map 的基本数据结构,再介绍 6.5 的背景和由来。 开始学习 6.5 吧! 了解 map 底层 我以前在写《深入理解 Go map:初始化和访问元素》时有介绍过 map 的基础数据结构。

Go 切片这道题,吵了一个下午!

大家好,我是煎鱼。 前几天听到咱 Go 读者交流群里的小伙伴私聊我,表示他们在群里一直在讨论一个问题 slice 相关的问题,众说纷纭。 今天和各位小伙伴们一起来研究一下,避免后续又踩一遍坑,共同进步! 问题代码 引起群内大范围讨论的代码如下: func main() { sl := make([]int, 0, 10) var appenFunc = func(s []int) { s = append(s, 10, 20, 30) fmt.Println(s) } fmt.