```go
type Girl struct {
name string
}
func (g *Girl) Appointment() {
fmt.Println("I appointment ",g.name)
}
func main(){
friends := []Girl{{"Juliet"},{"Emily"},{"Amy"}}
for _,friend := range friends{
defer friend.Appointment()
}
/*
打印结果:
I appointment Amy
I appointment Amy
I appointment Amy
*/
for _,friend := range friends{
f := friend
defer f.Appointment()
}
/*
打印结果:
I appointment Amy
I appointment Emily
I appointment Juliet
*/
}
```
1. 第一次循环输出:使用的是`for range`创建的`Value`进行,同时因为`Appointment`方法传入的是`Girl`类型的指针,最终在defer输出时,三个`Appointment`方法的接收者都是`Value`的地址,而最终`Value`地址指向的是`{"Amy"}`,即
2. 第二次循环输出:使用的是`f := friend`,其中`f`变量进行了`值拷贝`,即`将原切片的每个元素进行了深拷贝`,最终`Appointment`方法的接收者是与`friends`切片无关的三个`f`变量的地址,即`f1:{"Juliet"}`,`f2:{"Emily"}`,`f3:{"Amy"}`
#2
更多评论
用friend 接收range friends时,friend的地址始终是同一个,而下面friend每次都是赋值给新的地址f。defer是后进先出,所以打印的顺序是反的。
#1
附: `range`会发生什么:
```golang
// The loop we generate:
len_temp := len(range)
range_temp := range // <--- 会对切片进行引用的值拷贝
for index_temp = 0; index_temp < len_temp; index_temp++ {
value_temp = range_temp[index_temp]
index = index_temp
value = value_temp
original body
}
```
#3