揭露切片的真实面目

本节主要内容位于 runtime/slice.go, 基于 go1.16.4/amd64

创建一个切片十分简单,如下即可创建一个长度为 10 的 int 切片

1
slice := make([]int, 10)

但是具体是如何实现的呢,我们慢慢来看。

slice 结构

slice.go 中首先定义的就是 slice 结构体

1
2
3
4
5
type slice struct {
array unsafe.Pointer
len int
cap int
}

这样一看,其实 slice 也不是那么神奇,结构体中包含了一个指向实际数据的指针array,以及切片的长度 len 和切片的容量 cap

切片作为参数进行传递的时候,传递的不是整个结构体,实际上是传入了 slice 中的 array 数据指针,如果在函数内部修改了切片,那么同样会修改外部的切片。

阅读更多

字符串与切片转换

本节内容主要代码位于 runtime/string.go, 基于 go1.16.4/amd64

以下面的代码进行说明

1
2
3
slice := []byte{'h', 'e', 'l', 'l', 'o'}
slice2str := string(slice)
str2slice := []byte(slice2str)

slice to string

底层将 byte slice 转换成 string 的函数为 slicebytetostring

1
func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) 

这个函数接收三个参数,*tmpBuf 是一个指向 byte 数组的指针,ptr 指向 slice 第一个元素的地址, n 表示切片的长度。

阅读更多

字符串相加

本节内容主要代码位于 runtime/string.go

以下面的代码进行说明

1
2
3
a := "Hello "
b := "World "
_ = a + b

当执行 a+b 的时候,底层上调用的是 concatstrings,并且将a, b 两个操作数作为 slice 传递进去,如下:

阅读更多