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

Go是否支持增量构建?我来告诉你!

本文永久链接 – https://tonybai.com/2022/03/21/go-native-support-incremental-build Go语言以编译速度快闻名于码农界。这缘于Go在设计之初就选择抛弃其祖辈C语言的头文件包含机制,选择了以包(package)作为基本编译单元。Go语言的这种以包为基本构建单元的构建模型使得依赖分析变得十分简单,避免了C语言那种通过头文件分析依赖的巨大开销。在我的《Go语言精进之路》一书中,我也给出了Go编译速度快的三点具体原因,包括: ...

March 21, 2022 · 11 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

为什么有了Go module后“依赖地狱”问题依然存在

本文永久链接 – https://tonybai.com/2022/03/12/dependency-hell-in-go 如果所有Gopher都抛弃GOPATH构建模式,拥抱Go module构建模式;如果所有legacy Go package作者都能为自己的legacy package加上go.mod;如果所有Go module作者都严格遵守语义版本(semver)规范,那么Go将彻底解决“依赖地狱”问题。 ...

March 12, 2022 · 12 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

2021年Go语言盘点:厉兵秣马强技能,蓄势待发新征程

本文永久链接 – https://tonybai.com/2022/01/16/the-2021-review-of-go-programming-language 由于日常忙工作,闲时忙专栏,我早已策划的2021年Go语言盘点这篇文章一直拖到了2022年元旦之后才开始落笔。 2021年,Go迈过了其开源的第12个年头。虽然已经演进了10余年,但在编程语言这个领域中,Go依旧属于“小字辈”,仍处于快速的成长演化期。 纵观整个2021年,如果要用一句话来形容Go语言的发展,那就是厉兵秣马,蓄势待发。“厉兵秣马”这个成语的意思是把兵器磨快,把战马喂饱,形容做好战备,也比喻事前做好准备工作。那么2021年的Go究竟在为什么做准备呢?毫无疑问,它就是2022年泛型语法特性的落地。泛型既是Go社区最关注的语法特性,也是Go在语言特性方面的又一个“杀手锏”。 ...

January 16, 2022 · 12 min · Tony Bai