本文转自:http://meia.fun/article/1541470004286golang
学习切片时,被append这个方法困扰了半天:在main方法中把一个切片做为实参传递给另外一个函数,并在这个函数内调用append方法为切片形参添加一个元素后,main方法的切片实参竟然没有输出添加的元素。数组
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 9 var a []string = make([]string, 0, 10) 15 test(a) 16 fmt.Println(a) 17 } 18 19 func test(t []string) { 20 t = append(t, "a") 21 fmt.Println(t) 22 } 23 --------------------------------------------------------output 24 E:/go/bin/go.exe run template.go [D:/goProjects] 25 [a] 26 [] 27 成功: 进程退出代码 0.
首先要明白一点,切片是由指针(指向底层数组)、len、cap三个元素构成。在上面代码中a和t这两个切片的底层数组是相同的(但a和t是两个不一样的切片,golang中只有值传递,在调用test时copy了切片a给t),按理来讲两个切片的输出结果应该是同样的,但是输出的结果确不同,缘由是由于append方法不会修改原切片,只会返回更新(切片的长度、容量)后的切片并添加元素到底层数组或分配新的底层数组(在切片容量不足的时候),上面代码中其实两个切片底层共享的数组已经修改了的,可是golang在输出切片时仅输出切片长度内的内容,因此不扩展下切片 看不到另一个切片append的元素。app
代码修改以下,便可看到append的元素:函数
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 9 var a []string = make([]string, 0, 10) 10 test(a) 11 fmt.Println(a) 12 fmt.Println(a[:10]) 13 } 14 15 func test(t []string) { 16 t = append(t, "a") 17 fmt.Println(t) 18 }
23 --------------------------------------------------------output
24 E:/go/bin/go.exe run template.go [D:/goProjects] 25 [a] 26 []
[a ] 27 成功: 进程退出代码 0.
实际开发中,在golang 里面有个简单的原则,修改什么就传什么的指针,这里修改slice自身,就传slice的指针:学习
1 package main 2 3 import "fmt" 4 5 func main() { 6 s1 := make([]int, 0, 5) 7 test(&s1) 8 fmt.Println(s1) 9 } 10 func test(s *[]int) { 11 *s = append(*s, 3) 12 fmt.Println(*s) 13 }