如何解决我想知道为什么这两种方式的结果不同
func main() {
var a int = 10
var b int = 20
swap(&a,&b)
fmt.Println(a,b)
var c int = 10
var d int = 20
swap2(&c,&d)
fmt.Println(c,d)
}
func swap(x,y *int) {
*x = *y
*y = *x
}
func swap2(x,y *int) {
*x,*y= *y,*x
}
//我想知道为什么这两种方式的结果不一样
//20 20
//20 10
解决方法
swap2(&c,&d)
导致设置为 c
和 d
的值不同的原因是因为该函数由单个赋值语句组成,而 swap(&a,&b)
由两个赋值语句组成.赋值语句在 go 中有特定的求值顺序。来自language specifications:
任务分两个阶段进行。首先,左边的索引表达式和指针间接(包括选择器中的隐式指针间接)的操作数和右边的表达式都按通常的顺序计算。其次,分配按从左到右的顺序进行。
考虑到这一点,让我们注释 swap(x,y *int)
:
// x points to an int with value 10,// y points to an int with value 20.
*x = *y // 1.
*y = *x // 2.
第一个赋值语句先出现,所以这样做:
// x points to an int with value 10,// y points to an int with value 20.
*x = *y // 1. (value of int pointed to by x) = (value of int pointed to by y)
// Now x points to an int with value 20.
*y = *x // 2.
在第一个赋值语句完成后,运行第二个赋值语句:
// x points to an int with value 10,// y points to an int with value 20.
*x = *y // 1. (value of int pointed to by x) = (value of int pointed to by y)
// Now x points to an int with value 20.
*y = *x // 2. (value of int pointed to by y) = (value of int pointed to by x)
// Now y points to an int with value 20.
然而,因为 swap2
只使用一个赋值语句,所以我们必须注意发生的顺序。规范说左边的指针间接和右边的表达式同时计算:
// x points to an int with value 10
// y points to an int with value 20
*x,*y = *y,*x
// 1. (value of int pointed to by x),(value of int pointed to by y) = 20,10
其次,分配按从左到右的顺序进行。但是因为我们已经评估了语句的右侧,这些只是值。
// x points to an int with value 10
// y points to an int with value 20
*x,10
// 2. Now x points to an int with value 20,y points to an int with value 10
换句话说,swap2
和这个函数做同样的事情:
swap3(x,y *int) {
valueX := *x
valueY := *y
*x = valueY
*y = valueX
}
swap2
形式的优点是函数不会显式分配不必要的临时变量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。