值类型与引用类型,值传递与引用传递

简介: 值类型与引用类型,值传递与引用传递

值传递和引用传递


Go语言参数传递是传值还是传引用

一文整得明明白白~

Go全部都是值传递,不存在引用传递

值传递 是原始值copy出一份副本,然后传递; 引用传递 是直接传原始值的指针;

值传递并非不能修改原始值,当原始值是引用类型时(指针、map、slice、chan等这些),值传递就可以修改原始值 (值传递传的指针是原始值指针的副本,但两个指针都指向同一个地址)




值类型和引用类型


slice,map,channel,interface,func这5种数据类型 是引用类型,都(或者至少某个字段)是指针  (引用类型可以看作是对指针的封装)

(使用make函数创建的map,channel 其实都是一个指针,slice是其结构体SliceHeader的Data字段是指针)

// SliceHeader is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
// Moreover, the Data field is not sufficient to guarantee the data
// it references will not be garbage collected, so programs must keep
// a separate, correctly typed pointer to the underlying data.
type SliceHeader struct {
  Data uintptr
  Len  int
  Cap  int
}

int、float、bool、array、sturct 是值类型


string比较有争议,感觉是值类型,但有种说法也是引用类型


几种说法


说法1: “引用类型保存在堆上,值类型保存在栈上”?

这种说法是不准确的

首先不要纠结字面意思,Java中(byte、short、int、long、float、double)、字符型(char)、布尔型(boolean)这些基本类型数据直接保存在栈中,而类、接口、数组数据是保存在堆中,栈只是保存一个指向堆内存的指针。

一文理清 Go 引用的常见疑惑




浅拷贝与深拷贝


讨论值传递和引用传递时,其实就是看值类型变量和引用类型变量作为函数参数时,修改形参是否会影响到实参

在Go语言中除了五个引用类型,其他都是值类型:

  • slice
  • map
  • channel
  • interface
  • func()


引用类型作为参数时,称为浅拷贝,形参改变,实参数跟随变化.因为传递的是地址,形参和实参都指向同一块地址

值类型作为参数时,称为深拷贝,形参改变,实参不变,因为传递的是值的副本,形参会新开辟一块空间,与实参指向不同

如果希望值类型数据在修改形参时实参跟随变化,可以把参数设置为指针类型


Golang基础(闭包、值传递与引用传递)


需要注意的是,在 Go 语言中,闭包内部引用外部变量时,实际上是引用了外部变量的地址。因此,闭包的行为类似于引用传递,而不是像一般的函数参数那样的值传递。

一般认为这种类型才是真正意义上的闭包(即不传参数进去)

package main
func main() {
  i := 1
  func() {
    i = 2
    print(i)
  }()
  print(i)
}

实际上,我把这种情况也认为是闭包:

package main
func main() {
  i := 1
  func(i int) {
    i = 2
    print(i)
  }(i)
  print(i)
}

即传参进去,那里面的改动就不会影响外面,外面的改动也不会影响里面(在传进去那一刻就定住了~)


当然如果这样,里面的改动还是会改变外面的值

package main
func main() {
  i := 1
  func(k int) {
    i = 2
    print(i)
  }(i)
  print(i)
}
目录
相关文章
|
2月前
|
存储 Java C#
C# 中的值类型与引用类型
在 C# 编程中,值类型和引用类型的区别至关重要,直接影响内存管理、性能优化及编程模式选择。值类型直接存储数据(如 `int`、`float`),而引用类型存储数据的引用地址(如 `class`、`string`)。值类型的赋值涉及数据复制,适合小数据量;引用类型仅复制引用,适合大数据量处理但需关注垃圾回收。本文通过具体代码示例详细解析二者的定义、存储方式及性能影响,并提供实战案例分析及易错点避免方法,帮助读者更好地理解和应用。
59 2
|
存储 C# C++
值类型和引用类型
值类型和引用类型
值传递与引用数据类型传递
值传递与引用数据类型传递
43 0
|
开发框架 Java 数据库连接
基本数据类型与引用传递|学习笔记
快速学习基本数据类型与引用传递
|
存储 大数据 Java
你真的了解形参、实参、引用类型、值类型吗?
也许你可能知道引用传递、值传递以及标题所示的概念。但你是否真正了解它们为什么会这样? 引用类型和值类型究竟是什么? 引用传递与值传递的区别? 以及方法形参和实参的区别? 通过本篇文章将帮助大家进阶对于以上内容的了解。
2337 0
DOORS的引用类型
DOORS的引用类型包括:Project: 项目引用Folder: 文件夹引用Item: 项目或文件夹之内的项(项目、文件夹、模块)Module: 打开模块的引用Object: 对象的引用Link: 打开的源模块的链接引用LinkRef: 源模块关闭的链接引用AttrDef: 属性定...
1100 0
|
存储 数据格式 JSON
第183天:引用类型和值类型
一、内存分配 1、数值型内存分配 1 2 var num1; //这个时候不进行内存分配 3 var num3=9;//分配内存 4 var num4=num3;//会不会分配 5 6 // 这里到底分配还是不分配内存?? 7 // 答案 --分配内存 彼此拥有独立的内存空间,互不影响 8 console.
1009 0
方法的形式参数为引用数据类型时
方法的形式参数为引用数据类型:   基本数据类型(太简单,不是我今天要讲解的)   引用数据类型     1.方法的形式参数为类名时:需要该类的对象。(匿名对象的时候已经讲过了)     2.方法的形式参数为抽象类名时:需要该抽象类的子类对象。
998 0
【基础中的基础】引用类型和值类型,以及引用传递和值传递
一直在博客园怼人,非常惭愧。所以郑重决定: 好好写一篇干货,然后再接着怼人。 这是一起帮上陈百万同学的求助,讲了一会之后,我觉得很有些普世价值,干脆就发到园子来。面向小白,高手轻拍。   我们从最简单的说起(基础知识,懂的同学直接往下拉),直接上代码: static int amo...
1542 0