Web Analytics

len(s)表达式的求值结果究竟是常量还是变量?我来告诉你

本文永久链接 – https://tonybai.com/2022/03/24/the-result-of-a-len-expression-is-constant-or-variable len是Go预定义标识符,同时也是Go内置的预定义函数,通过go doc工具我们能查到len函数的doc如下: $go doc builtin.len package builtin // import "builtin" func len(v Type) int The len built-in function returns the length of v, according to its type: Array: the number of elements in v. Pointer to array: the number of elements in *v (even if v is nil). Slice, or map: the number of elements in v; if v is nil, len(v) is zero. String: the number of bytes in v. Channel: the number of elements queued (unread) in the channel buffer; if v is nil, len(v) is zero. For some arguments, such as a string literal or a simple array expression, the result can be a constant. See the Go language specification's "Length and capacity" section for details. 对于len函数,即便是Go初学者也不会陌生,因为在日常Go开发中,len是一个高频使用的函数。len的参数主要是复合数据类型的变量,比如数组(包括执行数组的指针类型)、切片、字符串、channel等,返回的结果是这些复合数据变量的长度(length),是一个int类型的值。太多细节我就不说了,大家可能也都很熟悉。我要说的是,关于len函数的一个大家可能不熟悉的或不太在意的地方,那就是len(s)表达式在什么时候的求值结果为一个常量(constant),什么时候的求值结果为变量。别忽视这个细节,这很可能让你的程序输出你意想不到的结果,下面我就来举例说明。 ...

March 24, 2022 · 7 min · Tony Bai

针对大型数组的迭代,for range真的比经典for loop慢吗?

本文永久链接 – https://tonybai.com/2022/03/19/for-range-vs-classic-for-loop-when-iterating-large-array Go语言推崇“一件事情仅有一个作法”!比如:Go仅保留一类循环控制语句,那就是经典版的for loop: for i := 0; i < 100; i++ { ... ... } 而像C语言支持的while、do…while等循环控制语句都被排除在Go简洁的语法之外。但为了方便Go开发者对复合数据类型的迭代,比如:数组、切片、channel以及map等,Go提供了一个变种for range loop,甚至对于map、channel进行遍历,仅能使用for range loop,经典版for loop根本不支持。 ...

March 19, 2022 · 7 min · Tony Bai

Go语言map类型变量背后的那些事儿

本文永久链接 – https://tonybai.com/2022/03/15/the-underlying-of-a-map-type-variable 切片(slice)和map是Go语言中最常用的两种原生复合数据类型,同时也是最容易使初学者感觉迷惑和“掉坑”的两个类型,这很大程度是因为Go runtime层的存在。什么是Go runtime层?可以参考我在《Go语言第一课FAQ》中的解释。 ...

March 15, 2022 · 5 min · Tony Bai

为什么这个T类型实例无法调用*T类型的方法

本文永久链接 – https://tonybai.com/2022/02/27/go-addressable 近期在“Go语言第一课”专栏后台看到一位学员的一则留言,如下图: 由于有课程上下文,所以我这里将问题的上下文重新描述一下。 在专栏的第25讲,我们学习了Go语言提供的一个“语法糖”,比如下面这个例子: type T struct { a int } func (t T) M1() { t.a = 10 } func (t *T) M2() { t.a = 11 } func main() { var t1 T t1.M1() t1.M2() var t2 = &T{} t2.M1() t2.M2() } Go语言的类型有方法集合(method set)的概念,以上面例子来说,类型T的方法集合为{M1},而类型*T的方法集合为{M1, M2}。不过方法集合仅用于判断某类型是否实现某接口类型。当我们通过类型实例来调用方法时,Go会提供“语法糖”。上面这个例子先声明了类型T的变量t1,我们看到它不仅可以调用其方法集合中receiver参数类型为T的方法M1,它还可以直接调用不属于其方法集合的、receiver参数类型为*T的方法M2。T类型的实例t1之所以可以调用receiver参数类型为*T的方法M2都是Go编译器在背后自动进行转换的结果,即t1.M2()这种用法是Go提供的“语法糖”:Go判断t1的类型为T,与方法M2的receiver参数类型*T不一致后,会自动将t1.M2()转换为(&t1).M2()。 ...

February 27, 2022 · 6 min · Tony Bai

Go GC如何检测内存对象中是否包含指针

本文永久链接 – https://tonybai.com/2022/02/21/how-gc-detect-pointer-in-mem-obj 众所周知,Go是带垃圾回收(GC)的编程语言,开发者通常不需要考虑对内存的管理,降低了心智负担。Go程序运行的时候,GC在背后默默辛劳地为开发者**“擦屁股”**:把无法reach到的内存对象定期地释放掉以备后续重用。 ...

February 21, 2022 · 8 min · Tony Bai

“Go语言第一课”结课了

本文永久链接 – https://tonybai.com/2022/02/17/go-first-course-close 就在家家户户刚刚过完虎年元宵佳节之际,我的Go语言专栏:《Tony Bai·Go语言第一课》也迎来了它的最后一讲结术语。 这门专栏的撰写开始于2021年5月中旬,翻看我用于管理专栏原始文稿的github仓库的commit log记录,这一有纪念价值的日子被精确定位在5月16日: ...

February 17, 2022 · 5 min · Tony Bai

Go究竟是否为空切片分配了底层数组

本文永久链接 – https://tonybai.com/2022/02/15/whether-go-allocate-underlying-array-for-empty-slice 这周在“Go语言第一课”的留言区看到一位同学的这样一个问题: 切片是Go语言中的一个重要的语法元素,也是日常Go开发中使用最为频繁的语法元素。有过Go语言开发经验的童鞋估计大多都知道空切片(empty slice)与nil切片(nil slice)比较的梗,这也是Go面试中的一道高频题。 ...

February 15, 2022 · 9 min · Tony Bai

Ian Lance Taylor:Go泛型使用的一般准则

本文永久链接 – https://tonybai.com/2021/11/07/using-generics-in-go 在近期Google Open Source Live的Go Day 2021环节,Go泛型的主要设计者Ian Lance Taylor做了Using Generics in Go的简短演讲(国内地址在这里)。这篇演讲的重点不是即将于Go 1.18版本降临的Go泛型的语法细节,而是介绍目前Go核心团队在设计、实现以及内部实践Go泛型的过程中积累的一些实践经验。Ian将这些经验总结成了这么一段小视频,旨在Go泛型落地之前,为Go社区提供一些Go泛型使用的通用指导原则。这里将演讲内容整理出来,供大家参考。 ...

November 7, 2021 · 11 min · Tony Bai

Go 1.17新特性详解:支持将切片转换为数组指针

本文永久链接 – https://tonybai.com/2021/08/18/go-language-specs-changes-in-go-1-17 Go属于那种极简的语言,从诞生到现在语言自身特性变化很小,不会像其他主流语言那样走“你有的我也要有”的特性融合路线。因此新语言特性对于Gopher来说属于“稀缺品”,属于“供不应求”那类事物^_^。这也直接导致了每次Go新版本发布,我们都要首先看看语言特性是否有变更,每个新加入语言的特性都值得我们去投入更多关注,去深入研究。下面我们就来深入Go 1.17版本中语言规范的一些变化! 1. 支持将切片转换为数组指针 在Go 1.17版本之前,我们可以将数组转换为切片,数组将成为转换后的切片底层存储数组,因此,通过切片可以直接改变数组中的元素,就像下面代码这样: ...

August 18, 2021 · 7 min · Tony Bai

Go 1.17中值得关注的几个变化

本文永久链接 – https://tonybai.com/2021/08/17/some-changes-in-go-1-17 Go核心开发团队在去年GopherCon大会上给Go泛型的定调是在2022年2月份的Go 1.18版本中发布,那可是自Go诞生以来语法规范变动最大的一次,这让包括笔者在内的全世界的Gopher们都满怀期待。 不过别忘了,在Go 1.18这个“网红版本”发布前,还有一个“实力派”版本Go 1.17呢!美国当地时间2021年8月16日,Go 1.17版本在经过两个RC版本之后正式发布!并且值得庆幸的是Go 1.17版本并没有过多受到Go 1.18版本这个“网红”的影响,Go 1.17默默地加入和优化了着实不少的特性。在这一篇文章中,我们就来看看Go 1.17版本中有哪些值得关注的变化。 ...

August 17, 2021 · 8 min · Tony Bai