当前位置:   article > 正文

Golang中的值传递和引用传递_golang 值传递和引用传递

golang 值传递和引用传递

一、前言

我在刚开始学习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"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

三、分析

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/206296
推荐阅读
相关标签
  

闽ICP备14008679号