go slice与函数传值的理解

go语言中所有的传值方式都是传值操作。

今天遇到了以下代码:

func main(){
      slice := make([]int ,1,1)
     fmt.Println(slice)
     change(s)
     fmt.Println(slice)
}

func change(s []int){
     s = append(s,2)
} 

输出结果是:

    0

    0

当时感到有些疑惑,学c或c++时,传入的参数为指针(数组首地址)时,change内这种直接修改参数s方法时可以修改值的,那么为何在go中无效呢?

1.go语言中,所有的参数传递都是值传递。

什么意思?就是在函数传递值时,都会拷一个副本传递给函数进行操作,就算是引用类型或者指针也不例外。

例如:

func main(){
        st := make([]int, 1, 1)
    fmt.Printf("st 原始切片的地址为:%p\n", &st)
    SliceTest(st)
}

func SliceTest(s []int) {
    fmt.Printf("st 传入后参数s的地址为:%p\n", &s)
    s = append(s, 3)
}

在我的电脑上的输出为:

st 原始切片的地址为:0xc000004540
st 传入后参数s的地址为:0xc000004560

可以看到,go语言中仅仅拷贝了st的一个副本进入SliceTest函数中进行操作,并未操作st本身。

2.go语言的切片,实际上是指向一个底层的数组。

在进入SliceTest函数时,s和st指向的底层数组都一样。

但是,经过append的操作,s原本指向的底层数组不满足追加元素的条件,所以要开辟一个新的数组来进行追加操作。

于是,s会指向一个新的底层数组。

但是这些操作和原切片st完全无关,因为s仅仅是st的副本,它们的地址不一样,s指向了新的数组,st并未改变,所以就有了开篇那段代码的结果。

对go的传值理解进一步加深。

原文地址:https://www.cnblogs.com/xuchen950317/p/12208732.html

时间: 2024-10-03 19:13:32

go slice与函数传值的理解的相关文章

golang的slice作为函数参数传值的坑

直接贴代码 func sliceModify(slice []int) { // slice[0] = 88 slice = append(slice, 6) } func main() { slice := []int{1, 2, 3, 4, 5} sliceModify(slice) fmt.Println(slice) } 返回的没变,坑爹的,这个设计太那啥了,可以正确跑出效果的版本如下: func sliceModify(slice *[]int) { *slice = append(*

[].slice.call(arguments,1) 个人理解

var arr = []; [] == arr; 假设 var arr = [1,2,3,4,5]; 那么 arr.slice(1,2) == [2]; 通过 slice.call 才能使用call显示绑定来实现 arguments 那么 var data = [].slice.call(arr,2); var data1 = [].slice.call(arr,1,3); data = [3,4,5]; data2 = [2,3]; 我的理解 通过 slice.call函数 将 arr 的内容

一次阿里面试后对函数本质的理解

一次阿里面试后对函数本质的理解 写在前面 环境:阿里的在线编程系统允许面试官在线考察面试者的编程能力. 考点:编程和理论. 编程:分为技术自驱力.异步操作.编程风格(颗粒小).变量作用域.DOM操作等. 理论:性能优化,浏览器运行机制,协议/标准等 本文侧重于编程,在编程中对函数的运用是写好程序的基础.(参考开发者技能修炼的五个等级中"第二阶梯:Developer,开发工程师""知道了变量.逻辑与函数的意义") 抛出一个问题 如何写一个信号灯?(参考一道关于Prom

对于linux下system()函数的深度理解(整理)

对于linux下system()函数的深度理解(整理) (2013-02-07 08:58:54) 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为是其他的代码影响到这个,或是内核驱动文件系统什么的异常导致,昨天有出现了这个问题,就随手百了一下度,问题出现了,很多人都说system()函数要慎用要少用要能不用则不用,system()函数不稳定?

[java学习笔记]java语言基础概述之函数的定义和使用&函数传值问题

1.函数 1.什么是函数? 定义在类中的具有特定功能的一段独立小程序. 函数也叫做方法 2.函数的格式 修饰符   返回值类型    函数名(参数类型  形式参数1, 参数类型  形式参数2-) {           执行语句(函数体);           return 返回值;       } 返回值类型:函数运行完成后输出的数据类型. 参数类型:是形式参数的数据类型. 形式参数:是一个变量,用于储存调用函数时传递给函数的实际参数. 实际参数:传递给形参的实际数据. return:结束函数

memcpy、memmove、memset及strcpy函数实现和理解

memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h>, 在C++中需要包含的头文件是#include其函数原型如下: void *memcpy(void *dest, const void *src, size_t n); 其功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 库函数中的memcpy不能处理sr

js:值类型/引用类型/内存回收/函数传值

把这4个概念放在一起写,因为它们是互通的 值类型:一个变量对应一块内存 var a=1; var b=a; a=2; 此时b还是等于1 就像你的克隆人,你心情不好去跳崖,他才不会傻乎乎地跟着你去跳 数值.boolean.null.undefined都是值类型 引用类型:有的博主这样比喻,一家店,它的引用就是它的钥匙 鉴于“作的精神”,我换一种比喻 一台电视机(内存)和它的遥控器关系(引用变量) 可以用遥控器换频道,但不可以用遥控器把电视变成冰箱 如果这电视不只一个遥控器,那么它们可以共同控制电视

对JS回调函数的一点理解

之前写的异步JS是纯译文,现在刚好工作了2个月,想谈谈我自己对JS回调函数的一点理解,欢迎渴望大家的指正和交流. 回调函数从形式上看就是把函数b作为参数传给函数a,在a的函数体里调用函数b 1 function a(b) { 2 b(); 3 } 4 function b() { 5 ... 6 } 这样做的意义是什么呢 1.控制执行流程,函数b只能在函数a执行后才执行 2.根据不同的需求,可以有各种各样的函数b 3.最重要的,是可以把通过函数a获取的数据传递给函数b 1 function a(

jquery的ajax()函数传值中文乱码解决方法介绍

前台 jQuery.post("/MailTemplate/SaveMailTemplate?Code=" + item.Code + "&DisplayName=" +encodeURI   (item.DisplayName) + "&Body=" +encodeURI(item.Body), {}, function (data) {                                if (data == 'S