go语言学习--2.函数

目录

1.函数分类

2.函数的声明和定义

3.函数传参

4.函数返回值

5.递归调用


为完成某一功能的程序指令(语句)的集合,称为函数。

1.函数分类

在Go语言中,函数是第一类对象,我们可以将函数保持到变量中。函数主要有具名匿名之分,包级函数一般都是具名函数,具名函数是匿名函数的一种特例,当匿名函数引用了外部作用域中的变量时就成了闭包函数,闭包函数是函数式编程语言的核心。

举例代码如下:

  • 具名函数:就和c语言中的普通函数意义相同,具有函数名、返回值以及函数参数的函数。
func Add(a, b int) int {return a+b
}
  • 匿名函数:指不需要定义函数名的一种函数实现方式,它由一个不带函数名的函数声明和函数体组成。
var Add = func(a, b int) int {return a+b
}

解释几个名词如下:

闭包函数:返回为函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。


一级对象:支持闭包的多数语言都将函数作为第一级对象,就是说函数可以存储到变量中作为参数传递给其他函数,最重要的是能够被函数动态创建和返回。


包:go的每一个文件都是属于一个包的,也就是说go是以包的形式来管理文件和项目目录结构的。

2.函数的声明和定义

Go 语言函数定义格式如下:

func fuction_name([parameter list])[return types]{函数体
}
解析
func函数由func开始声明
function_name函数名称
parameter list参数列表
return_types返回类型
函数体函数定义的代码集合

3.函数传参

Go语言中的函数可以有多个参数和多个返回值,参数和返回值都是以传值的方式和被调用者交换数据。在语法上,函数还支持可变数量的参数,可变数量的参数必须是最后出现的参数,可变数量的参数其实是一个切片类型的参数。

 当可变参数是一个空接口类型时,调用者是否解包可变参数会导致不同的结果,我们解释一下解包的含义,代码如下:

func main(){var a = []int{1, 2, 3}Print(a...)   // 解包Print(a)	  // 未解包
}func Print(a ...int{}) {fmt.Println(a...)
}

以上当传入参数为a...时即是对切片a进行了解包,此时其实相当于直接调用Print(1,2,3)。当传入参数直接为 a时等价于直接调用Print([]int{}{1,2,3})

4.函数返回值

不仅函数的参数可以有名字,也可以给函数的返回值命名。

在 Go 语言中,defer 关键字用于延迟(defer)函数的执行,直到包含 defer 语句的函数返回之前。defer 语句会将函数推迟到当前函数执行完成后执行,不论函数是正常返回还是出现异常。这在资源管理、错误处理等方面非常有用。

举例代码如下:

func Find(m map[int]int, key int)(value int, ok bool) {value,ok = m[key]return
}

如果返回值命名了,可以通过名字来修改返回值,也可以通过defer语句在return语句之后修改返回值,举例代码如下:

func mian() {for i := 0 ; i<3; i++ {defer func() { println(i) }}
}// 该函数最终的输出为:
// 3
// 3
// 3

以上代码中如果没有defer其实返回值就是0,1,2,但defer语句会在函数return之后才会执行,也就是或只有以上函数在执行结束return之后才会执行defer语句,而该函数return时的i值将会达到3,所以最终的defer语句执行printlin的输出都是3。

defer语句延迟执行的其实是一个匿名函数,因为这个匿名函数捕获了外部函数的局部变量v,这种函数我们一般叫闭包。闭包对捕获的外部变量并不是传值方式访问,而是以引用的方式访问。

这种方式往往会带来一些问题,修复方法为在每一轮迭代中都为defer函数提供一个独有的变量,修改代码如下:

func main() {for i := 0; i < 3; i++ {i := i // 定义一个循环体内局部变量idefer func(){ println(i) } ()}
}func main() {for i := 0; i < 3; i++ {// 通过函数传入i// defer 语句会马上对调用参数求值// 不再捕获,而是直接传值defer func(i int){ println(i) } (i)}
}

5.递归调用

Go语言中,函数还可以直接或间接地调用自己,也就是支持递归调用。Go语言函数的递归调用深度逻辑上没有限制,函数调用的栈是不会出现溢出错误的,因为Go语言运行时会根据需要动态地调整函数栈的大小。这部分的知识将会涉及goroutint和动态栈的相关知识,我们将会在之后的博文中向大家解释。

它的语法和c很相似,格式如下:

func recursion() {recursion() /* 函数调用自身 */
}func main() {recursion()
}

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

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

相关文章

少儿编程 2024年3月电子学会图形化编程等级考试Scratch二级真题解析(判断题)

2024年3月scratch编程等级考试二级真题 判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 26、下列积木块运行结果为false 答案&#xff1a;错 考点分析&#xff1a;考查积木综合使用&#xff0c;重点考查逻辑或积木的使用&#xff0c;或运算是只…

游戏公司面试题系列-CocosCreator实现虚拟摇杆控制角色移动中心旋转自转小球割草旋转逻辑

游戏公司面试题系列-CocosCreator实现虚拟摇杆控制角色移动&中心旋转自转小球&割草旋转逻辑<&#xff01;&#xff01;&#xff01;文章末尾有完整代码下载链接地址&#xff01;&#xff01;&#xff01;> Hello大家好&#xff01;今天我们来用最新的CocosCreat…

python|drop的应用

drop 删除列B 删除索引为1的行 删除列为‘A’&#xff0c;‘C’的列&#xff0c;axis表示方向 删除时保留原始 DataFrame&#xff08;使用 inplaceFalse&#xff09; 删除时直接修改原始 DataFrame&#xff08;使用 inplaceTrue&#xff09;

java数据结构与算法刷题-----LeetCode628. 三个数的最大乘积

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 排序选择线性搜索最值 排序 解题思路&#xff1a;时间复杂度O( …

[Algorithm][双指针][快乐数]详细解读 + 代码实现

题目链接本题中&#xff0c;将快慢指针抽象了两个数 slow每次变化一次&#xff0c;fast每次变化两次&#xff0c;即可达到"快慢指针"效果 "快慢指针"在此题中&#xff0c;用于判环 由于两"指针"速度并不一样&#xff0c;在快指针总是会追上慢指针…

网络通信流程

建立完tcp请求再发起http请求 开启系统代理之后&#xff0c;以clash verge为例 127.0.0.1:7897&#xff0c;假设hci.baidu.com的IP为153.37.235.50 发起对hci.baidu.com的HTTP请求&#xff0c;由于开启了系统代理不进行DNS解析&#xff0c;浏览器调用socket()获得一个socket&a…

Lustre架构介绍的阅读笔记-HSM

本文是在阅读Introduction to Lustre* Architecture的Lustre HSM System Architecture时的笔记。 Hierarchical Storage Management (HSM) is a collection of technologies and processes designed to provide a cost-effective storage platform that balances performance, …

Redis7(二)数据类型及其用法

一、概述 命令不区分大小写&#xff0c;key区分大小写 数据类型针对value String List Set Hash ZSet bitmap GEO HyperLogLog Stream bitfield 二、String <K,V> 1、设值/取值 getrange key index1 index2 getrange key 0 -1//获取所有的值 SETRANGE KEY_N…

线程池实践篇

文章目录 配置线程池参数定义参数实体bean配置线程池使用 配置线程池参数 定时任务线程池基础参数 # 定时任务线程池基础参数 task:pool:corePoolSize: 5 # 核心线程数maxPoolSize: 20 # 设置最大线程数keepAliveSeconds: 300 # 设置线程活跃时间&#xff0c;单位秒queueCapa…

使用 Go-Ora 连接到 Oracle 数据库

前文 《 一鍵啓動 Oracle 23c Free 》 介绍了如何使用容器技术快速拉起 Oracle 23c 数据库。 这个开发者版本可以很便捷的拉起、测试、销毁&#xff0c;对开发者是非常友好的。 本文将介绍如何使用 Go 语言构建项目&#xff0c;并连接到 Oracle 数据库。 Go 环境配置 本文使用的…

第十四天--指针函数的练习

1.a个学生&#xff0c;有b门课程成绩&#xff0c;求不及格的学生的学号&#xff0c;和不合格的科目成绩 思路&#xff1a;定义一个数组存放a个学生,b门课程的成绩---在main函数中用for循环判断n个学生是否有不合格的成绩&#xff08;hine&#xff09;---定义指针指向指针函数&…

如何将本地websocket服务端从本地暴露至公网实现客户端远程连接

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

Rust语言入门第一篇-环境搭建

Rust语言入门第一篇 Rust官网 一&#xff0c;环境搭建 1、C开发环境配置 Rust 语言的底层是依赖于 C/C 编译器的。在安装 Rust 编译器时&#xff0c;通常会自动安装所需的 C/C 编译环境&#xff0c;以便 Rust 能够生成可执行文件或库。因此&#xff0c;在安装 Rust 之前&…

Docker之数据卷和Dockerfile

目录 一、Docker数据管理 二、数据卷 创建数据卷 查看数据卷 删除数据卷 挂载数据卷 三、数据卷容器 创建数据卷容器 测试数据卷容器 备份数据卷容器 还原数据卷容器 四、Dockerfile 什么是Dockerfile 基本结构 常用指令 快速入门 编写Dockerfile文件 构建镜…

一些考研经验

前言 考研结束已有半个月&#xff0c;之前一直想写经验贴&#xff0c;奈何感觉自己本身就比较菜&#xff0c;考了两年才堪堪上岸&#xff0c;所以有些犹豫&#xff0c;拖拖沓沓到现在&#xff0c;思虑再三最终决定把自己对于考研的一些拙见记录一下&#xff0c;供各位参考。 …

安全升级,智能领航:RFID技术推动铁路锁控系统进入新时代

随着我国铁路运输行业的快速发展&#xff0c;铁路安全运营的重要性日益凸显&#xff0c;为了提高铁路运输安全性&#xff0c;降低人为操作失误&#xff0c;航连科技提出了一种基于RFID技术的铁路智能锁控系统解决方案&#xff0c;旨在为我国铁路安全运营提供有力支持。 一、系统…

第3章 数据定义语言DDL

文章目录 第3章 DDL语言&#xff1a;数据定义语言3.1 MySQL的数据类型3.2 表的创建&#xff1a;create3.3 表的删除&#xff1a;drop3.4 快速创建表3.5 快速删除表中的数据&#xff1a;truncate3.6 修改表结构&#xff1a;alter 第5章 约束5.1 非空约束&#xff1a;not null5.2…

LeetCode:2009. 使数组连续的最少操作数(排序 Java)

目录 2009. 使数组连续的最少操作数 题目描述&#xff1a; 实现代码与解析&#xff1a; 排序 去重 双指针 原理思路&#xff1a; 滑动窗口 原理思路&#xff1a; 2009. 使数组连续的最少操作数 题目描述&#xff1a; 给你一个整数数组 nums 。每一次操作中&#xff0c…

点云从入门到精通技术详解100篇-基于激光点云和视觉融合的智能车前方障碍物检测(下)

目录 4 基于传感器信息融合的前方障碍物检测及跟踪 4.1 融合算法总体结构 4.2 传感器时空同步

C++:VS dump调试(2)

之前写的&#xff1a; C&#xff1a;VS2019调试dump文件-CSDN博客 1、需要dump文件【这个一般是客户现场收集的】 2、对应的pdb文件【这个是软件编译时候生成的】 3、代码【有可能只有自己负责模块的代码&#xff0c;没有全部代码&#xff0c;但是基本调试也是只会用到自己部…