目录
陷阱小程序
(例子引用自golang随笔之slice+append的陷阱_cheems~的博客-CSDN博客)
package main
import "fmt"
func main(){
s1 := []int{1,2}
s2 := s1
s2 = append(s2,3)
Test1(s1)
Test2(s2)
fmt.Println(s1,s2)
}
func Test1(s []int){
s = append(s,0)
for i:= range s{
s[i]++
}
}
// 选项
A:[2,3] [2,3,4]
B:[1,2] [1,2,3]
C:[1,2] [2,3,4]
D:[2,3,1] [2,3,4,1]
大家可以先做一下,看下自己的答案是不是跟正确答案不一样。
问题击破
先来公布一下陷阱程序的答案:C
下面来对答案进行一个剖析
从陷阱程序main函数开始:
1、首先,我们来看一下s1和s2的一些信息,如example1.1。
// 程序分解 example 1.1
package main
import (
"fmt"
)
func main() {
s1 := []int{1, 2}
s2 := s1
// s1信息
fmt.Printf("s1: %v, len: %d, cap: %d, address: %p\n", s1, len(s1), cap(s1), &s1)
// s2信息
fmt.Printf("s2: %v, len: %d, cap: %d, address: %p\n", s2, len(s2), cap(s2), &s2)
// s1中元素信息
fmt.Println("*******************s1 start**********************")
for i := range s1 {
fmt.Printf("ele: %v, address: %p\n", s1[i], &s1[i])
}
fmt.Println("*******************s1 end**********************")
// s2中元素信息
fmt.Println("*******************s2 start**********************")
for j := range s2 {
fmt.Printf("ele: %v, address: %p\n", s2[j], &s2[j])
}
fmt.Println("*******************s2 end**********************")
}
// 输出:
s1: [1 2], len: 2, cap: 2, address: 0xc000010030
s2: [1 2], len: 2, cap: 2, address: 0xc000010048
*******************s1 start**********************
ele: 1, address: 0xc00001c030
ele: 2, address: 0xc00001c038
*******************s1 end**********************
*******************s2 start**********************
ele: 1, address: 0xc00001c030
ele: 2, address: 0xc00001c038
*******************s2 end**********************
根据输出可以看出main函数中s1和s2除了address(切片地址)以外,其他的信息都是一样的,但是注意到s1 start中和s2 start打印两个切片中元素信息时,两