Golang中的值传递和引用传递

本文解析了Go语言中的值传递和引用传递概念,并通过实例对比了数组、切片和映射表在函数调用中的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

我在刚开始学习golang的时候,被值传递和引用传递困扰了一段时间,因为我之前是学习Java的,深受Java面向对象思想的影响,转成golang的时候就会想不通结构体等类型(看起来像是Java中自己定义的类),为什么会是值传递,所以总结一篇文章来通过例子简单分析一下这个问题。

二、例子

先说结论:golang中都是采用值传递,即拷贝传递,也就是深拷贝。没有引用传递。之所有有些看起来像是引用传递的场景,是因为Golang中存在着引用类型,如slice、map、channel、function、pointer这些天生就是指针的类型,在传递的时候是复制的地址。引用类型作为参数时,称为浅拷贝,形参改变,实参数跟随变化。因为传递的是地址,形参和实参都指向同一块地址。(切片是引用类型,数组是值类型)切片和数组的区别

package main

import(
	"fmt"
)

func main(){
	//map
	m := make(map[int]string)
	m[0] = "a"
	m[1] = "b"
	changeMap(m)
    fmt.Printf("map:%+v", m)  //输出 map:map[0:aaa 1:b]
    fmt.Println()

	//array
    var a = [2]string{"a", "b"}
    changeArray(a)
    fmt.Printf("array:%+v", a) //输出array:[a b]
    fmt.Println()

     //slice
    var s = []string{"a", "b"}
    changeSlice(s)
    fmt.Printf("slice:%+v", s) //输出slice:[aaa b]
}

func changeMap(m map[int]string) {
    m[0] = "aaa"
}

func changeArray(a [2]string) {
    a[0] = "aaa"
}

func changeSlice(s []string) {
    s[0] = "aaa"
}

三、分析

通过上面的例子可以看出来map和slice都是引用类型,即函数内部是可以改变参数的值的。而array是值类型,不管函数内部如何改变参数,都是改变的拷贝值,并未对原值进行处理。
所以,golang中除了特定的几个指针类型之外,其他的所有类型,包括自己创建的结构体都是深层复制,即值类型。像是结构体,不像Java中只是把指针赋值给接收的变量,而是新开辟了一块内存空间,把所有的属性复制过去了,创建了一个一模一样的结构体。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值