学习函数式编程、可变参数及 defer - GO语言从入门到实战

函数是⼀等公⺠、学习函数式编程、可变参数及 defer - GO语言从入门到实战

函数是⼀等公⺠、学习函数式编程、可变参数及 defer

函数是⼀等公⺠

在Go语言中,函数可以分配给一个变量,可以作为函数的参数,也可以作为函数的返回值。这样的行为就可以理解为函数属于一等公民。

与其他主要编程语⾔的差异

  1. 可以有多个返回值:与其他一些编程语言不同,Go语言中的函数可以返回多个值。这使得函数可以更有效地处理和传递多个结果。例如,你可以使用两个变量来接收函数的两个返回值。
package fn_testimport ("fmt"
)
func divideAndRemainder(dividend, divisor int) (int, int) {quotient := dividend / divisorremainder := dividend % divisorreturn quotient, remainder
}a, b := divideAndRemainder(10, 3)
fmt.Println(a, b) // 输出:3 1
  1. 所有参数都是值传递:在Go语言中,函数参数是通过值传递的。当你将一个变量作为参数传递给函数时,函数会创建该变量的一个副本,而不是直接操作原始变量。这有时会让人产生错觉,认为传递的是引用,但实际上是值传递。但是,对于切片(slice)、映射(map)和通道(channel)这样的引用类型,情况会有所不同。它们在函数间传递时会传递引用,而不是复制整个数据。这意味着如果你在函数内部修改了这些类型的参数,会影响原始变量的值。
package fn_testimport ("fmt"
)
func modifySlice(s []int) {s[0] = 100
}nums := []int{1, 2, 3, 4, 5}
modifySlice(nums)
fmt.Println(nums) // 输出:[100 2 3 4 5]
  1. 函数可以作为变量的值:在Go语言中,函数可以作为变量保存和使用。这使得你可以将函数作为参数传递给其他函数,或者将它们赋值给变量。这在实现高阶函数和函数式编程范式时非常有用。
package fn_testimport ("fmt"
)
func add(a, b int) int {return a + b
}addition := add // 将函数add赋值给变量addition
fmt.Println(addition(2, 3)) // 输出:5
  1. 函数可以作为参数和返回值:和其他编程语言一样,Go语言的函数可以作为参数传递给其他函数,也可以作为返回值返回。这种能力使得你可以在函数之间传递和返回操作,从而增强代码的模块化和复用性。

这些特性使得Go语言的函数比其他许多编程语言更加灵活和强大。

函数:可变参数及 defer

可变参数

可变参数允许我们在调用函数时传入任意数量的整数。函数的功能是将所有传入的整数相加,然后返回总和。

package mainimport "fmt"func sum(ops ...int) int {s := 0for _, op := range ops {s += op}return s
}func main() {fmt.Println(sum(1, 2, 3, 4, 5)) // 输出: 15fmt.Println(sum(10, 20, 30))    // 输出: 60
}

在上述例子中,sum函数被调用了两次,每次都传入了一些整数。第一次传入的整数是1, 2, 3, 4, 5,总和是15;第二次传入的整数是10, 20, 30,总和是60。

defer 函数

defer语句可以用来释放资源、关闭文件、打印日志等,它具有很高的灵活性,是Go语言中常用的编程技巧之一。使用defer语句需要注意以下几点:

  1. defer语句必须放在函数内部;
  2. 多个defer语句的执行顺序是与其压入栈中的顺序相反的;
  3. defer语句中的变量在执行时会被记录下来,而不是在执行时读取;
  4. defer语句中的函数会在执行时被调用,而不是在压入栈时调用。
package mainimport "testing"func TestDefer(t *testing.T) {t.Log("Started")defer func() {t.Log("Clear resources")}()// 其他测试代码
}

defer语句位于TestDefer函数的末尾,当这个函数执行结束时,defer语句中的函数将会被执行,打印出"Clear resources"。

下面提供函数应用的代码案例:

package fn_testimport ("fmt""math/rand""testing""time"
)
//函数会生成两个随机数,一个在0到9之间,一个在0到19之间。
func returnMultiValues() (int, int) {return rand.Intn(10), rand.Intn(20)
}//函数接受一个函数作为参数,返回一个新的函数。新函数会计算传入函数的运行时间,并打印出来。
func timeSpent(inner func(op int) int) func(op int) int {return func(n int) int {start := time.Now()ret := inner(n)fmt.Println("time spent:", time.Since(start).Seconds())return ret}
}//函数会让程序暂停1秒,然后返回传入的运算。
func slowFun(op int) int {time.Sleep(time.Second * 1)return op
}//首先调用returnMultiValues函数并打印结果,然后创建了一个新的函数tsSF,它内部调用了slowFun并打印其运行时间,最后调用tsSF函数并打印结果。
func TestFn(t *testing.T) {a, _ := returnMultiValues()t.Log(a)tsSF := timeSpent(slowFun)t.Log(tsSF(10))
}//函数接收任意数量的整数参数,并返回它们的和。
func Sum(ops ...int) int {ret := 0for _, op := range ops {ret += op}return ret
}//函数调用了Sum函数两次,分别传入4个和5个整数,并打印结果。
func TestVarParam(t *testing.T) {t.Log(Sum(1, 2, 3, 4))t.Log(Sum(1, 2, 3, 4, 5))
}//函数打印"Clear resources."。
func Clear() {fmt.Println("Clear resources.")
}//首先打印"Start",然后触发一个panic,最后执行defer Clear(),清除资源。
func TestDefer(t *testing.T) {defer Clear()fmt.Println("Start")panic("err")	//panic是一种用于处理程序错误和异常情况的机制,类似于其他语言的异常
}

学习Go语言主要是多练,多找些代码段写写,不懂可以私聊咨询。
码字不易,如果该文章有用,请多多关注或者赞赏,谢谢!

欢迎关注云尔Websites CSDN博客

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

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

相关文章

hive数据库操作,hive函数,FineBI可视化操作

1、数据库操作 1.1、创建数据库 create database if not exists myhive;use myhive;1.2、查看数据库详细信息 desc database myhive;数据库本质上就是在HDFS之上的文件夹。 默认数据库的存放路径是HDFS的:/user/hive/warehouse内 1.3、创建数据库并指定hdfs存…

POI 和 EasyExcel 操作 Excel

一、概述 目前操作 Excel 比较流行的就是 Apache POI 和阿里巴巴的 easyExcel。 1.1 POI 简介 Apache POI 是用 Java 编写的免费开源的跨平台的 Java API,Apache POI 提供 API 给 Java 程序对 Microsoft Office 格式文档读和写的常用功能。POI 为 “Poor Obfuscati…

【Vuex+ElementUI】Vuex中取值存值以及异步加载的使用

一、导言 1、引言 Vuex是一个用于Vue.js应用程序的状态管理模式和库。它建立在Vue.js的响应式系统之上,提供了一种集中管理应用程序状态的方式。使用Vuex,您可以将应用程序的状态存储在一个单一的位置(即“存储”)中,…

Android Studio: unrecognized Attribute name MODULE

错误完整代码: ������ (1.8.0_291) �г����쳣������&#xff…

LeetCode(力扣)416. 分割等和子集Python

LeetCode416. 分割等和子集 题目链接代码 题目链接 https://leetcode.cn/problems/partition-equal-subset-sum/ 代码 class Solution:def canPartition(self, nums: List[int]) -> bool:sum 0dp [0]*10001for num in nums:sum numif sum % 2 1:return Falsetarget …

linux用户管理,用户权限命令详解

一.用户管理 Linux 同时可以支持多个用户,每个用户对自己的文件设备有特殊的权利,能够保证用户之间互不干扰,就像手机开了助手一样,同时登陆多个 qq 账号,当硬件配置非常高时,每个用户还可以同时执行多个任务&#xf…

[CSAWQual 2019]Web_Unagi - 文件上传+XXE注入(XML编码绕过)

[CSAWQual 2019]Web_Unagi 1 解题流程1.1 分析1.2 解题2 思考总结1 解题流程 这篇博客讲了xml进行编码转换绕过的原理:https://www.shawroot.cc/156.html 1.1 分析 页面可以上传,上传一句话php失败,点击示例发现是xml格式,那么就是XXE注入了 点击about得到flag位置: Fla…

微服务10-Sentinel中的隔离和降级

文章目录 降级和隔离1.Feign整合Sentinel来完成降级1.2总结 2.线程隔离两种实现方式的区别3.线程隔离中的舱壁模式3.2总结 4.熔断降级5.熔断策略(根据异常比例或者异常数) 回顾 我们的限流——>目的:在并发请求的情况下服务出现故障&…

翻译docker官方文档(残缺版)

Build with docker(使用 Docker 技术构建应用程序或系统镜像) Overview (概述) 介绍(instruction) 层次结构(Layers) The order of Dockerfile instructions matters. A Docker build consists of a series of ordered build ins…

3、在 CentOS 8 系统上安装 PostgreSQL 15.4

PostgreSQL,作为一款备受欢迎的开源关系数据库管理系统(RDBMS),已经存在了三十多年的历史。它提供了SQL语言支持,用于管理数据库和执行CRUD操作(创建、读取、更新、删除)。 由于其卓越的健壮性…

虚幻引擎:如何才能对音波(声音资产)进行逻辑设置和操作

案列:调整背景音乐大小 1.创建一个SoundCue 2.进入创建的SoundCue文件 3. 创建音效类和音效类混合 4.进入SoundCue选择需要的音效类 5.然后音效类混合选择相同的音效类 6.然后蓝图中通过节点进行控制音量大小

每日leetcode_LCP01猜数字

每日leetcode_LCP01猜数字 记录自己的成长&#xff0c;加油。 题目出处&#xff1a;LCP 01. 猜数字 - 力扣&#xff08;LeetCode&#xff09; 题目 解题 class Solution {public int game(int[] guess, int[] answer) {int count 0;for (int i 0 ; i< guess.length; i){…