【Go函数详解】二、参数传递、变长参数与多返回值

文章目录

  • 一、传递参数
    • 1. 按值传参
    • 2. 引用传参
      • 2.1 特殊情况
        • 2.1.1 切片slice
        • 2.1.2 字典map
  • 二、变长参数
    • 1. 基本定义和传值
      • 1.1 基本定义
      • 1.2 传值
        • 1.2.1 普通传值
        • 1.2.2 传递切片
    • 2. 任意类型的变长参数(泛型)
  • 三、多返回值
    • 1. 命名返回值


一、传递参数

1. 按值传参

Go语言默认使用按值传参来传递参数,即传递参数值的一个副本:
函数接收到传递进来的参数后,会将参数值拷贝给声明该参数的变量(形式参数,简称形参),如果在函数体中有对参数值做修改,实际上修改的是形参值,这不会影响到实际传递进来的参数值(简称实参)。

func add(a, b int) int  {a *= 2b *= 3return a + b
}func main()  {x, y := 1, 2z := add(x, y)fmt.Printf("add(%d, %d) = %d\n", x, y, z)   //add(1, 2) = 8
}

x、y把值传递给a、b,主要原因是x、y的内存地址与a、b的内存地址并不相同,可以看作是两个值相等的不同变量,所以修改a、b的值并不会改变x、y的值。

2. 引用传参

如果想要实现在函数中修改形参值可以同时实参值,需要通过引用传参来完成,此时传递给函数的参数是指一个指针,而指针代表的是实参的内存地址,修改指针引用的值即修改内存地址中存储的值,所以实参的值也会被修改。

! 注意:这种情况下,传递的变量是地址值的拷贝,所以从本质上讲还是按值传递。

func add(a, b *int) int {*a *= 2*b *= 3return *a + *b
}func main()  {x, y := 1, 2z := add(&x, &y)fmt.Printf("add(%d, %d) = %d\n", x, y, z)
}

在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型默认使用引用传参。

2.1 特殊情况

以下具体分析详见:(留个坑)

2.1.1 切片slice

把slice作为函数参数传递,若在函数内slice发生扩容的话,会让函数内外原本指向同一个底层数组的两个slice变量,分别指向两个不同的底层数组

2.1.2 字典map

把map作为函数参数传递,若在函数内map发生扩容的话,函数内外的map变量指向的底层内存仍是一致的。

二、变长参数

所谓变长参数指的是函数参数的数量不确定,即可以传递任意数量的参数到指定函数。合适地使用变长参数,可以让代码更简洁,尤其是输入输出类函数,fmt.Println的参数就是典型的变长参数。

1. 基本定义和传值

1.1 基本定义

在参数类型前加上...前缀,就可以将该参数声明为变长参数

func myfunc(numbers ...int) {for _, number := range numbers {fmt.Println(number)}
}

1.2 传值

1.2.1 普通传值
myfunc(1, 2, 3, 4, 5) 

函数 myfunc() 接受任意数量的参数,这些参数的类型全部是 int

1.2.2 传递切片

传递切片时需要末尾加上...作为标识,表示对应的参数类型是变长参数:

slice := []int{1, 2, 3, 4, 5}
myfunc(slice...)
myfunc(slice[1:3]...)

注:形如...type格式的类型只能作为函数的参数类型存在,并且是函数的最后一个参数

之所以支持传入切片,是因为从底层实现原理上看,类型...type本质上是一个切片,也就是[]type,这也是为什么上面的numbers可以用for循环来获取每个传入的参数值。

2. 任意类型的变长参数(泛型)

即指定变长参数类型为interface{}

func myPrintf(args ...interface{}) {for _, arg := range args {switch reflect.TypeOf(arg).Kind() {case reflect.Int:fmt.Println(arg, "is an int value.")case reflect.String:fmt.Printf("\"%s\" is a string value.\n", arg)case reflect.Array:fmt.Println(arg, "is an array type.")default:fmt.Println(arg, "is an unknown type.")}}
}func main() {myPrintf(1, "1", [1]int{1}, true)
}

在这里插入图片描述
这里实现的是泛型功能,Go语言并没有在语法层面提供对泛型的支持,目前只能自己通过反射和interface{}类型实现。
interface{}是一个空接口,可以用于表示任意类型。但这个范围过于宽泛,像C语言中的void一样,我们根本不知道真正传递进来的参数到底是什么类型的,这在强类型的静态语言中是不能接受的,为了保证代码类型安全,需要在运行时通过反射对数据类型进行检查,以便让程序在预设的轨道内运行,避免因为类型问题导致程序崩溃。

三、多返回值

Go语言与其他编程语言一大不同之处在于支持多返回值,这才处理程序出错的时候非常有用。

func add(a, b *int) (int, error) {if (*a == 0 || *b == 0) {err := errors.New("只支持非负整数相加")return 0, err}*a *= 2*b *= 3return *a + *b, nil
}func main()  {x, y := -1, 2z, err := add(x, y)if err != nil {fmt.Println(err.Error())return}fmt.Printf("add(%d, %d) = %d\n", x, y, z)
}

如上,通过error指定多返回一个表示错误信息的、类型为error的返回值,函数的多个返回值之间可以通过逗号分隔,并且在最外面通过圆括号包起来。

1. 命名返回值

在设置多返回值时,可以对返回值进行变量命名,这样可以在函数中直接对返回值进行赋值,而不必每次都按照指定的返回值格式返回多个变量了。

func add(a, b *int) (c int, err error) {if (*a == 0 || *b == 0) {err = errors.New("只支持非负整数相加")return}*a *= 2*b *= 3c = *a + *breturn
}

这种机制避免了每次进行 return 操作时都要关注函数需要返回哪些返回值,为开发者节省了精力,尤其是在复杂的函数中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/412823.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

customRef 与 ref

ref() 我们已经很熟悉了,就是用来定义响应式数据的,其底层原理还是通过 Object.defineprotpty 中的 get 实现收集依赖( trackRefValue 函数收集),通过 set 实现分发依赖通知更新( triggerRefValue 函数分发 )。我们看看 ref 的源码就知道了 …

微气象在线监测系统:宏观层面的电网灾害预防和应急管理

微气象受局部地形(如山谷、河谷)、地物(如建筑物、森林)和地面条件(如水面、农田)的影响较大,而大范围气象环境则更多地受气候系统和天气模式的控制。输电线路微气象监测的主要目的是为了评估和…

YOLOv8环境搭建、创建数据集、训练推理教程(超级详细)

yolov8和yolov10 是一个流派,和yolov5区别还挺大,所以尝试使用yolov8来进行模型训练,下面是详细使用流程: 一、环境搭建 1.1 Anaconda安装 Anaconda是一个强大的开源数据科学平台,它将很多好的工具整合在一起,极大地…

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题——(共九套)(每套四十题)

华为海思招聘-芯片与器件设计工程师-数字芯片方向- 机试题-题目分享——共九套(每套四十题) 岗位——芯片与器件设计工程师 岗位意向——数字芯片 真题题目分享,完整版带答案(有答案和解析,答案非官方,未仔细校正&am…

论文阅读:VideoMamba: State Space Model for Efficient Video Understanding

论文地址:arxiv 摘要 为了解决视频理解中的局部冗余与全局依赖性的双重挑战。作者将 Mamba 模型应用于视频领域。所提出的 VideoMamba 克服了现有的 3D 卷积神经网络与视频 Transformer 的局限性。 经过广泛的评估提示了 VideoMamba 的能力: 在视觉领…

Hbuilder创建的项目(uniApp + Vue3)中引入UnoCSS原子css引擎

这里是UnoCSS的官网介绍 UnoCS通过简化和优化CSS的编写过程来提高Web开发的效率和可维护性。好处是: 提升开发效率提升开发效率提高一致性增强灵活性易于维护方便的集成与配置 同时还支持预设变量和规则。这些可参看官网进行配置。Unocss通过其原子化方法、高度的…

第二证券:静态市盈率与动态市盈率有什么区别?

市盈率(PE),是指投资者愿意为每一元净利润所支付的价格。 股票的市盈率股票价格(P)/每股净利润(EPS),或者用公司其时总市值/公司上一年总净利润。 动态市盈率与静态市盈率的区别&a…

<数据集>遥感航拍飞机和船舶和识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:19973张 标注数量(xml文件个数):19973 标注数量(txt文件个数):19973 标注类别数:2 标注类别名称:[ship,plane] 序号类别名称图片数框数1ship17575416292plane239815…

对比 PDAF、CDAF 和 LAAF 自动对焦技术

深入解析相位检测自动对焦(PDAF) 相位检测自动对焦(PDAF,Phase Detection Auto Focus)是一种高效的自动对焦技术,广泛应用于现代数码相机、无反相机和智能手机摄像头中。为了更好地理解 PDAF,我…

基于协同过滤算法的电影推荐系统的设计与实现(论文+源码)_kaic

摘 要 现在观看电影已逐渐成为人们日常生活中最常见的一种娱乐方式,人们通常会在周末或在休息、吃饭时间不由自主地在各种视频软件中搜索当前火热的影视节目。但是现在的视频软件电影推荐功能不够完善,所以需要开发出一套系统来使用户只需要简单操作就能…

华为云征文|部署私有云和文档管理系统 Kodcloud

华为云征文|部署私有云和文档管理系统 Kodcloud 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 应用场景1.3 对比普通ECS 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Kodcloud3.1 Jellyfin 介绍3.2 Docker 环境搭建3.3 Jell…

【智能算法改进】路径规划问题的多策略改进樽海鞘群算法研究

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】樽海鞘群算法(SSA)原理及实现 2.改进点 无标度网络策略 复杂网络在图论中可以用边和节点表示, Barabasi 等于1999年通过分析大量的数据提出了无标度网络模型. 该网络…

人像比对-人证比对-人脸身份证比对-人脸身份证实名认证-人脸三要素对比-实人认证

​ 人证比对API接口,全称为人脸身份证比对API接口,也被称为人脸实名认证API接口或实人认证API接口。这种接口服务主要用于将提供的人脸图片和对应的身份证照片、姓名、身份证号码进行比对,以此验证用户的身份。以下是关于人证比对API接口的详…

[易聊]软件项目测试报告

一、项目背景 随着互联网发展,各种各样的软件,比如游戏、短视频、购物软件中都有好友聊天功能,这是一个可在浏览器中与好友进行实时聊天的网页程序。“ 易聊 ”相对于一般的聊天软件,可以让用户免安装、随时随地的通过浏览器网页…

UDP英译汉网络词典

这里我们用UDP实现一个简单的英译汉小词典。我们还是仿照前一篇的UDP编程,将各自的组件封装起来,实现高内聚低耦合。 一. 字典翻译功能实现 首先我们将我们的字典知识库放在txt文本中。 apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 ha…

浮毛粘毛器可以彻底去除吗?独家揭秘值得入手浮毛空气净化器

有没有养猫五年以上还是单猫的铲屎官?能不能分享一下怎么才能控制住不养新猫。 从我养第一只猫开始,每次看到别人家的小幼猫,就控制不住的想养。到现在,家里已经有了7只猫,而前段时间楼下那只小三花又差点让我破例。不…

Keil5 Debug模式Watch窗口添加的监控变量被自动清除

Keil5 Debug模式Watch窗口添加的监控变量被自动清除 问题解决记录 问题描述:每次进入Debug模式时,watch窗口里面上一次调试添加的监控变量都会被全部清掉 如图: 退出Debug模式后,重新进入Debug模式: 解决方法&…

INFO:一种基于向量加权平均的高效优化算法【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2022年,I Ahmadianfar受到基于向量加权平均方法启发,提出了加权平均向量优化算法(weIghted meaN oF vectOrs, INFO)。 2.算法原理 2.1算法…

在线任务分发系统开发架构分析

在线任务分发系统的架构分析是一个综合性的过程,涉及多个技术层面和功能模块的设计。以下是对在线任务分发系统架构的详细分析: 一、系统概述 在线任务分发系统是一个集任务发布、分配、执行、监控及反馈于一体的综合平台,它通过互联网技术实…

超详细带你学习go高性能web框架----fiber

go-fiber-fast go-fiber 主要定位为一个轻量级、高性能的 Web 框架,但其灵活性使得它可以通过与其他库的集成,构建出强大而多功能的应用程序,满足不同的业务需求,和gin一样轻量级别的路由,但是性能特别是极端性能比gin好一些,都可以通过整合其…