代码如下
```
package main
import "fmt"
func swap(a, b *int) (*int, *int) {
fmt.Printf("a2: %v %p\n", *a, a)
a, b = b, a
fmt.Printf("a3: %v %p\n", *a, a)
return a, b
}
func main() {
a := 3
b := 4
fmt.Printf("a1: %v %p\n", a, &a)
c, d := swap(&a, &b)
fmt.Printf("a4: %v %p\n", a, &a)
fmt.Println(*c, *d)
}
```
打印输出:
a1: 3 0xc0000120b8
a2: 3 0xc0000120b8
a3: 4 0xc0000120d0
a4: 3 0xc0000120b8
问题:
1.golang指针类型无法运算,为什么swap函数中 a,b=b,a可以执行?
2.从swap中打印的a2、a3来看,a指向的地址已经发生了变化。操作的是指针类型,跳出swap函数之后a应该还是修改后的值,为什么a4与a3的打印结果不一致?
```go
package main
import "fmt"
func swap(newA, newB *int) (*int, *int) {
// 这里的newA执行的是调用中传递进来的变量地址,也就是说main中传递尽量的变量a得的地址(&a)被复制保存到了这个newA变量,newB同理
fmt.Printf("a2: %v %p\n", *newA, newA) // 所以这里输出的和main输出保持一致;是:a2: 3 0xc0000120b8
// 这一步将newA和newB执行的内存地址做了交互;也就是说newA和newB变量的指向做了变更
newA, newB = newB, newA
// 此时打印newA时,其实打印的是调用者最初传递进来的newB执行内存地址的值和地址
fmt.Printf("a3: %v %p\n", *newA, newA)
return newA, newB
}
func main() {
a := 3
b := 4
// 这一步不用解释
fmt.Printf("a1: %v %p\n", a, &a)
// c指向的是b内存地址;d指向的是a内存地址
c, d := swap(&a, &b)
// 这里a的内存地址没变,所以值也不变。记住上面swap(&a, &b)调用时,是将&a, &b的内存地址传给了swap函数的形参newA和newB;swap内部交互newA和newB变量的内存指向,并不会影响这里a和b的指向(也就是一楼说的“此a,b非彼a,b”);但是如果swap中修改newA或者newB指向内存地址中的值,就会影响这里a和b的值
fmt.Printf("a4: %v %p\n", a, &a)
fmt.Println(*c, *d)
}
```
稍微做个修改,楼主可能会清晰点
#5
更多评论