【golang学习笔记】Go语言中参数的传递是值传递还是引用传递

前言

Go中所有的参数传递都是值传递,是对数据进行一个拷贝。具体分为引用类型和非引用类型

  • 非引用类型(值类型):int,string,float,bool,数组和struct;

    特点:值类型变量声明后,直接存的就是对应的数据。

  • 引用类型:指针,slice,map,channel,接口,函数等。

    特点:变量存放的是一个内存地址值,这个地址值指向的空间存的才是最终的值。内存通常在堆中分配,当没有任务变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,通过GC回收。

这里我所说的值传递,意思就是引用类型在传递的时候,其实是将值实际地址,也就是当前变量所存的地址拷贝一份进行传递。

值传递

代码:

package main

import "fmt"

func main() {
    
    
   var value = 3

   //因为int为值类型 所以需要取地址符
   fmt.Printf("modify before addr: %p value: %d\n", &value, value)

   modify(value)

   //再次打印
   fmt.Printf("modify after main addr: %p value: %d\n", &value, value)
}

func modify(value int) {
    
    

   value = 0

   fmt.Printf("modify addr: %p value: %d\n", &value, value)
}

输出:

modify before addr: 0xc000018080 value: 3
modify addr: 0xc000018088 value: 0
modify after main addr: 0xc000018080 value: 3

可以发现地址两个地址不是同一个地址,并且也不会对实参进行修改

扫描二维码关注公众号,回复: 16505035 查看本文章

引用传递

此时我们使用slice进行举例说明

代码:

package main

import "fmt"

func main() {
    
    

   value := []int{
    
    1, 2, 3}
   fmt.Printf("modify begin addr: %p value: %d\n", value, value)
   fmt.Printf("modify begin addr: %p value: %d\n", &value, value)

   modify1(value)

   fmt.Printf("modify after addr: %p value: %d\n", value, value)
   fmt.Printf("modify after addr: %p value: %d\n", &value, value)
}

func modify1(value []int) {
    
    
   value[0] = 0
   fmt.Printf("modify addr: %p value: %d\n", value, value)
   fmt.Printf("modify addr: %p value: %d\n", &value, value)
}

结果:

modify begin addr: 0xc0000b4000 value: [1 2 3]
modify begin addr: 0xc0000a4018 value: [1 2 3]
modify addr: 0xc0000b4000 value: [0 2 3]
modify addr: 0xc0000a4078 value: [0 2 3]
modify after addr: 0xc0000b4000 value: [0 2 3]
modify after addr: 0xc0000a4018 value: [0 2 3]

可以发现
在这里插入图片描述

这个地址不论是实参还是函数内部地址都是相同的,而另外一个地址是不同的。

这是因为切片是一个引用类型,然后这个变量里面保存的是实际数据的地址,而在进行参数传递的时候,我们传递的是保存的地址,而不是保存这个地址的地址。也就是说我们将这个地址值传递过去了,然后函数内部开辟了一个内存将这个地址存起来了,然后我们就可以看见无论是在外面还是里面,这个传递的地址值是不变的。而保存这个地址的地址是改变的。这也是为什么是golang是值传递的原因。

在这里插入图片描述

所以在函数中对数据进行修改,其实是对保存地址中的数据进行修改,所以会影响到函数外。

猜你喜欢

转载自blog.csdn.net/qq_45795744/article/details/125929752