Go切片是值传递还是引用传递?

这篇具有很好参考价值的文章主要介绍了Go切片是值传递还是引用传递?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go没有引用传递和引用类型!!!

很多人有个误区,认为涉及Go切片的参数是引用传递,或者经常听到Go切片是引用类型这种说法,今天我们就来说一下方面的问题。

什么是值传递?
将实参的值传递给形参,形参是实参的一份拷贝,实参和形参的内存地址不同。函数内对形参值内容的修改,是否会影响实参的值内容,取决于参数的本身

什么是引用传递?
将实参的地址传递给形参,函数内对形参值内容的修改,将会影响实参的值内容。Go语言是没有引用传递的,在C++中,函数参数的传递方式有引用传递。
————————————————
版权声明:本文为CSDN博主「走,我们去吹风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_51991615/article/details/130345352

首先明确几个点:

  • 1、官方明确表明:Go中没有引用类型,链接在这
    Go切片是值传递还是引用传递?
  • 2、官方明确表明:Go中function所有参数的传递都是值传递,链接在这
    Go切片是值传递还是引用传递?
  • 3、Golang默认是值传递,即拷贝传递;
  • 4、有些值头部head中含有地址,如(切片,map类型),所以导致看起来像是引用传递

那么问题来了,既然Go没有引用类型的说法,且function的参数都是值传递,为什么当我使用切片slice或者map等类型作为参数时,有传引用的错觉呢?

/**
 * 测试切片不是引用传递
 */
func TestPassByValue(t *testing.T) {
	sli := []int{0, 1, 2, 3, 4}
	fmt.Printf("sli的地址:%p\n", unsafe.Pointer(&sli))
	fmt.Printf("sli[0]的地址:%p\n", unsafe.Pointer(&sli[0])) 
	//unsafe.Pointer(&sli[0])是一个指针不假,但它也仅仅是切片结构内包含的一个值
	t.Log(sli)
	modifySlice(sli)
	t.Log(sli)
}
func modifySlice(s []int) {
	//slice的底层大概如下:
	type slice struct {
		array unsafe.Pointer   // 就是这里的unsafe.Pointer(&s[0]),因为是值传递,所以这个指针是跟外面一样的
		len int
		cap int
	}
	fmt.Printf("参数的地址:%p\n", unsafe.Pointer(&s))
	fmt.Printf("参数[0]的地址: %p \n", unsafe.Pointer(&s[0]))
	s[0] = 111 //此时直接修改参数的值,外面的值也跟着同步修改
	s[1] = 222 //但当你进行append操作或者二倍扩容时,&s[0]的地址就会改变,数外的切片就不会跟着改变了。
}

总结
之所以有传引用的错觉是因为slice本质是一个结构体,结构体内有个指针值,而这个值指向切片的第一个元素,因为是值传递,所以slice内的这个指针跟函数外边是一样的,此时,你在函数内修改切片的某个值,函数外会跟着改变。 但当你进行append操作或二倍扩容时,这个指针值就会改变,此时,你再次在函数内对切片进行修改,函数外不会跟着改变。文章来源地址https://www.toymoban.com/news/detail-747971.html

到了这里,关于Go切片是值传递还是引用传递?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于切片参数传递的问题

    前言:在 Golang 中函数之间传递变量时总是以值的方式传递的,无论是 int,string,bool,array 这样的内置类型(或者说原始的类型),还是 slice,channel,map 这样的引用类型,在函数间传递变量时,都是以值的方式传递,也就是说传递的都是值的副本。 在使用ioutil的ReadAll方法时查看了

    2024年02月06日
    浏览(33)
  • rust踩雷笔记(1)——切片传参和解引用赋值

    最近学习rust,网上资料还是很有限,做题遇到的问题,有时需要自己试验。把自己做题过程遇到的问题,和试验的结论,做一些简单记录。 阅读下列文字和代码 用切片(的引用)做参数要非常小心,切片中的某个元素直接用=赋值,用的是copy方式而不是所有权转移(实践证

    2024年02月12日
    浏览(34)
  • 【Java】引用传递?值传递?

    引用传递和值传递,从上学那会儿就开始强调的概念,不管你是计算机相关专业还是自学Java,一定听过这么一句话: 方法调用参数如果是对象,那就是引用传递,如果是基本数据类型,就是值传递。 比如:function(Object o)就是引用传递,function(int i)就是值传递。这两个概念似

    2024年02月05日
    浏览(34)
  • Go 空切片与nil切片

    在 Go 语言中,空切片和 nil 切片是两种不同的概念。 空切片是一个长度和容量都为 0 的切片。你可以通过 make 函数或者切片字面量来创建一个空切片,例如 s := make([]int, 0) 或者 s := []int{}。 空切片不是 nil,即 s != nil。 空切片已经分配了内存空间,所以你可以直接向空切片中

    2024年02月20日
    浏览(36)
  • Java的值传递和引用传递

    两个a都保存在栈中,没有交集,互不影响,所以不会发生改变     数组在栈里申明了,但具体数据是保存在堆中,栈中保存的是具体数据的内存引用地址,a和a[1]是同一个内存地址,所以了修改a[1]了,会改动到a。 面试时怎么回答: 值传递不会改变本身,基本数据类型都是

    2023年04月20日
    浏览(33)
  • Go 空切片 VS nil切片

    在 Go 语言中,空切片和 nil 切片是两种不同的概念。 空切片是一个长度和容量都为 0 的切片。你可以通过 make 函数或者切片字面量来创建一个空切片,例如 s := make([]int, 0) 或者 s := []int{}。 空切片不是 nil,即 s != nil。 空切片已经分配了内存空间,所以你可以直接向空切片中

    2024年02月20日
    浏览(49)
  • Java 中的值传递和引用传递 ?

    一. 介绍 值传递: 值传递(Pass-by-Value)当我们向方法传递参数时,实际上是将该参数的值进行拷贝,并将拷贝后的值传递给方法内部。在方法内部对参数进行修改不会影响原始变量的值。 引用传递: 引用传递(Pass by reference)是指方法调用时实参(即传入方法的参数)是一

    2024年02月13日
    浏览(33)
  • Python值传递和引用传递(详细分析)

    目录 1. 形参与实参 2. Python的数据类型 3.Python变量及其赋值 3.1 不可变对象赋值 3.2 可变对象赋值 3.3 变量删除 3.4 变量赋值总结 4.Python函数的参数传递 4.1 参数传递定义 4.2 不可变对象的参数传递 4.3 可变对象的参数传递 5.总结 6 不可变与可变对象赋值对比: 6.1 单层源对象 6.

    2024年02月02日
    浏览(26)
  • Python 中的值传递 和 引用传递

    position 是一个 tensor; 下面这段代码第一行,如果在函数里面修改 position 会导致 下面的 position 也会发生变化 在第二行加上 clone 函数 之后,才可以保证执行完 第二行之后 的 position 的数值不会发生变换。

    2024年02月13日
    浏览(34)
  • Java 引用传递

    引用传递是 Java 中一个重要的概念,它与值传递不同,可以使得函数或方法可以修改传入的对象。本文将介绍 Java 中的引用传递,包括其定义、实现方式、与值传递的区别以及示例代码。 在 Java 中,变量可以存储基本类型的值或对象的引用。当一个对象的引用被传递给一个方

    2024年02月09日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包