分类看一下Go的值传递和引用传递:
值传递:将值传递给函数
/* 引入单测包 */
import (
"testing"
)
func TestSwap(t *testing.T) {
x := 100
y := 200
swap(x, y)
println("x:", x)
println("y:", y)
}
/* 定义相互交换值的函数 */
func swap(x, y int) int {
var temp int
temp = x /* 保存 x 的值 */
x = y /* 将 y 值赋给 x */
y = temp /* 将 temp 值赋给 y*/
return temp;
}
结果:
个人理解:传给swap函数的相当于一个值,swap函数会把形参作为一个局部变量新建,局部变量的修改,不影响原值。
引用传递:将指针(引用)传递给函数
import (
"testing"
)
func TestSwap(t *testing.T) {
x := 100
y := 200
swapByPoint(&x, &y)
println("x:", x)
println("y:", y)
}
func swapByPoint(x, y *int) int {
var temp int
temp = *x /* 保存 x 的值 */
*x = *y /* 将 y 值赋给 x */
*y = temp /* 将 temp 值赋给 y*/
return temp;
}
结果:函数里面的修改,影响了原值
个人总结:当传递指针给函数时,类似于传递了内存地址给函数,函数会对这块内存做修改,所以会影响原值。
值传递-类的实例
import (
"testing"
)
type Person struct{
Name string
}
func TestChangeName(t *testing.T) {
person := new(Person)
person.Name = "aaaaaaa"
changeName(*person)
println("name:", person.Name)
}
func changeName(person Person) {
person.Name = "bbbbbb"
}
结果:未改变原值
引用传递-类的实例
func TestChangeName(t *testing.T) {
person := new(Person)
person.Name = "aaaaaaa"
changeName(person)
println("name:", person.Name)
}
func changeName(person *Person) {
person.Name = "bbbbbb"
}
结果:影响了原值
小结:传变量只会被当做局部变量,传指针才会影响原值
数组
传递值
func TestChangeName(t *testing.T) {
person1 := new(Person)
person1.Name = "a1"
person2 := new(Person)
person2.Name = "a2"
personList := make([]Person, 0)
personList = append(personList, *person1)
personList = append(personList, *person2)
changeNames(personList)
for _, person := range personList {
println("person.Name:", person.Name)
}
}
func changeNames(personList []Person) {
for _, person := range personList {
person.Name = "CCCC"
}
}
结果:没影响原值,原因是遍历personList时,获得的person相当于新创建的一个局部变量
TODO:看一下局部变量的内存地址,是不是真的是新建的
通过下标遍历数组:会影响原值
func TestChangeName(t *testing.T) {
person1 := new(Person)
person1.Name = "a1"
person2 := new(Person)
person2.Name = "a2"
personList := make([]Person, 0)
personList = append(personList, *person1)
personList = append(personList, *person2)
changeNames(personList)
for _, person := range personList {
println("person.Name:", person.Name)
}
}
func changeNames(personList []Person) {
for index, _ := range personList {
personList[index].Name = "CCCC"
}
}
结果:通过数组下标访问数组,能影响到原值
数组中存放指针,也能修改原值
func TestChangeName(t *testing.T) {
person1 := new(Person)
person1.Name = "a1"
person2 := new(Person)
person2.Name = "a2"
personList := make([]*Person, 0)
personList = append(personList, person1)
personList = append(personList, person2)
changeNames(personList)
for _, person := range personList {
println("person.Name:", person.Name)
}
}
func changeNames(personList []*Person) {
for _, person := range personList {
person.Name = "CCCC"
}
}
结果:
总结:
- 如果想在调用的函数中,修改原值,最好是传指针。
- 如果不想传指针,可以把结果值返回,在调用的地方进行赋值