go语言之路

golang基础之引用传递和按值传递

修改外部变量值

传递指针给函数不但可以节省内存(因为没有复制变量的值),而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用 return 返回。如下的例子,reply 是一个指向 int 变量的指针,通过这个指针,我们在函数内修改了这个 int 变量的数值。

package main

import "fmt"

func main() {
   var outside int = 0
   changeByPtr(&outside)
   fmt.Println(outside)
   change := changeByReturn(outside)
   fmt.Println(change)
}

//通过指针修改 引用传值
func changeByPtr(o *int) {
   *o += 2
}

//通过函数返回值 按值传递
func changeByReturn(o int) int {
   return o+2
}

按值传递和引用传递

Go函数中默认使用按值传递来传递参数

也就是传递参数的副本

函数接受参数副本后,在使用变量的过程中可能对副本的值进行修改,但不会影响到原来的变量

如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号)传递给函数,这就是引用传递,此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针指的值指向的地址上的值不会被复制;我们可以通过这个指针的值来修改这个值指向的地址的值。

几乎在任何情况下,传递指针的消耗都比传递副本少

在函数调用时,像切片slice,字典map,接口interface,通道channel这样的引用类型都是默认使用引用传递(即使没有显示的指出指针)

探究一下引用传递和按值传递

package main

import "fmt"

type MyStruct struct {
   name string
   age int
}

func main() {
   //test struct
   mystruct := new(MyStruct)
   mystruct.changeInfo()
   fmt.Println(mystruct.name, mystruct.age)

   //test slice
   myslice := []int32{1, 2, 3, 4}
   fmt.Println(myslice)
   changeSlice(myslice)
   fmt.Println(myslice)
}

func (m *MyStruct) changeInfo() {
   //*m.name = "gocloudcoder"
   //*m.age = 21
   m.name = "gocloudcoder"
   m.age = 21
}

func changeSlice(s []int32) {
   s[0] = 0
   s[1] = 1
   s[2] = 2
   s[3] = 3
}

漫画第一集之新年篇

上一篇

一文解惑intel、amd和arm

下一篇

你也可能喜欢

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片

个人微信公众号

we-tuiguang

qq交流群

群号:1046260719

微信扫一扫

微信扫一扫