append方法的使用说明:

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//	slice = append(slice, elem1, elem2)
//	slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//	slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

append方法的使用案例

package main

import(
	"fmt"
	"testing"
)

func TestAppend(t *testing.T){
	s := make([]int, 0 , 1)
	fmt.Printf("Addr of s :  %p \n", &s)
	fmt.Println(s)

	s1 := append(s, 1)
	fmt.Printf("Addr of s1 :  %p \n", &s1)
	fmt.Println(s1)

	s2 := append(s, 2)
	fmt.Printf("Addr of s2 :  %p \n", &s2)
	fmt.Println(s2)

	fmt.Printf("Addr of s1 again:  %p \n", &s1)
	fmt.Println(s1)

	s3 := append(s, 1, 2)
	fmt.Printf("Addr of s3 :  %p \n", &s3)
	fmt.Println(s3)
	
}

执行结果分析:

F:\golang\demo\append>go test -v
=== RUN   TestAppend
Addr of s :  0xc0000044e0
[]
Addr of s1 :  0xc000004520
[1]
Addr of s2 :  0xc000004560
[2]
Addr of s1 again:  0xc000004520
[2]
Addr of s3 :  0xc0000045c0
[1 2]
--- PASS: TestAppend (0.01s)
PASS
ok      append_test     0.040s

golang 切片是引用类型,它的底层实现是数组,在数组上标记一段数据就是切片拥有的数据。

切片 s 初始化为[],len=0,cap=1,第一次打印为 s = []

切片 s1 := append(s, 1) 由于只增加了一个数据,切片不会扩容,底层数组的元素变成1,所以s1 = [1]

切片 s2 := append(s, 2) 由于只增加了一个数据,切片不会扩容,底层数组的元素变成2,所以s1 = [2]。此时再次打印s1=[2],这是容易让人迷惑的地方,因为切片是引用类型,s1 变量指向的底层数组在s2 变量声明时元素变为2,所以s1 = [2]。这个也符合引用类型变量的数据处理特征。

切片 s3 := append(s, 1, 2) 由于增加了2个数据,切片需要扩容,golang新建容量=2的底层数组 [2] {0, 0}作为新切片的引用,所以s3 = [1, 2]。