文章目录

  • 1. Go语言的函数语法
  • 2. Go 函数中的可变长参数
  • 3. Go函数中的延迟函数 deffer

1. Go语言的函数语法

先介绍一下Go语言的函数和其他语言 函数之间的差异,其中有一些已经在之前的总结中提到过。

函数在Go语言中是属于一等公民。

  • 可以有多个返回值
  • 所有参数都是值传递:slice ,map, channel 会有传引用的错觉
  • 函数可以作为变量的值
  • 函数可以作为参数和返回值

比如如下测试函数:

func returnMultiValue() (int, int) {return rand.Intn(10), rand.Intn(20) // 两个返回值
}func TestFunction(t *testing.T) {a,_ := returnMultiValue() // 可以通过 符号 '_' 来表示不获取第一或第二个返回值t.Log(a)
}

输出如下:

=== RUN   TestFunctionTestFunction: function_test.go:16: 1
--- PASS: TestFunction (0.00s)

函数作为变量,参数,以及返回值
编写如下几个测试函数:

/*
通过函数式编程
以下是一个计时函数,统计函数执行耗时的函数
入参:函数
返回值:函数可以统计任意 函数的执行时间,只需要将被统计函数名称作为入参传入该函数即可
*/
func calcTimeSpent(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}
}func slowTest(op int) int {time.Sleep(time.Second * 1) // sleep 1秒return op
}func TestSpentTime(t *testing.T) {sp := calcTimeSpent(slowTest) // 传入耗时函数t.Log(sp(10))
}

输出如下:

=== RUN   TestSpentTime
time spent : 1.004237117TestSpentTime: function_test.go:36: 10
--- PASS: TestSpentTime (1.00s)

2. Go 函数中的可变长参数

基本语法如下:

func sum( args ... int) int{s := 0for _,op := range args{s += op}return s
}

相同类型的参数不再需要指定具体的个数,只需要传入’…’ 即可被转化为一个参数数组完成函数内部的逻辑处理需要,减少实际开发过程相同类型函数的重写或者重载的代码量。

测试以上变参 函数如下:

func sum(args ... int) int {s := 0for _,op := range args{ //将传入的参数转换为数组s += op}return s
}func TestChangeArgs(t *testing.T) {t.Log(sum(1,2,3)) // 可以传入3 个,或者 下面的4个参数t.Log(sum(4,16,8,9))
}

最终的输出如下:

=== RUN   TestChangeArgsTestChangeArgs: function_test.go:57: 6TestChangeArgs: function_test.go:58: 37
--- PASS: TestChangeArgs (0.00s)

3. Go函数中的延迟函数 deffer

通过defer关键字声明一个函数,用来表示这个函数属于一个延迟函数。

即使函数在执行过程中异常退出,该函数调用的deffer函数也会正常执行(这个机制的实现还是比较有趣的,有点像C++的智能指针)。
利用延迟执行的机制,能够完成应用的垃圾回收功能。

关于deffer函数的测试代码如下:

func DefferFun() {fmt.Println("defer func run")
}
func TestDeferFun(t *testing.T) {defer DefferFun()t.Log("Started")panic("Failed") // panic 表示不可修复的错误,会让当前程序停止执行,并退出,但这里不影响defer函数的执行。fmt.Println("end")`在这里插入代码片`
}

输出如下:

=== RUN   TestDeferFunTestDeferFun: function_test.go:66: Started
defer func run
--- FAIL: TestDeferFun (0.00s)
panic: Failed [recovered]panic: Failed

如果将panic函数去掉,让程序正常执行,可以看到defer函数是在所有函数执行完成之后才会输出。

=== RUN   TestDeferFunTestDeferFun: function_test.go:66: Started
end
defer func run #所有函数逻辑执行完成 之后才执行
--- PASS: TestDeferFun (0.00s)

可以看到defer 即使延迟执行,仍然可以在发生panic 异常的时候正常输出。

Go 分布式学习利器(8)-- Go的函数相关推荐

  1. Go 分布式学习利器(16) -- go中可复用的package构建

    通过本文,你将了解go 语言中如何将自己的package构建到项目中 以及如何将远程(github)的package构建到项目中. 1. 构建本地的package package 是可复用模块的基本单 ...

  2. Go 分布式学习利器(11)-- Go语言通过单链表 实现队列

    一个小实验,将之前学习的Go相关的语法做个总结. 包括: Go语言接口特性 Go语言封装特性 Go语言 变量,指针,函数 语法 GO语言 条件和循环语句 的语法 GO语言的测试程序 通过链表实现一个队 ...

  3. Go:分布式学习利器(1) -- 开发环境搭建 + 运行第一个go程序

    文章目录 为什么要学习 go 开发环境搭建 -- MAC 运行第一个go程序 go 函数的返回值设置 go 函数的命令行参数 为什么要学习 go 在如下几个应用场景的需求下产生了go: 超大规模分布式 ...

  4. Go 分布式学习利器(20)-- Go并发编程之多路选择和超时控制,channel的关闭和广播

    Select 多路选择 基本使用语法如下: select {case ret := <-retCh1: //阻塞事件,等待channel1的消息t.Logf("result %s \n ...

  5. Go 分布式学习利器(19)-- Go并发编程 之 CSP(communicating sequential processes) 机制

    文章目录 前言 CSP 特点 CSP代码 演示 1. 正常流程的代码 2. CSP 未设置buffer 代码 3. 设置指定大小的channel buffer 总结 前言 CSP 这个名词大家会比较陌 ...

  6. Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全

    Go语言中通过Groutine 启动一个Go协程,不同协程之间是并发执行的,就像C++/Java中线程之间线程安全是一个常见的问题. 如下Go 语言代码: func TestConcurrent(t ...

  7. Go 分布式学习利器(17)-- Go并发编程之协程机制:Grountine 原理及使用

    文章目录 1. Thread VS Groutine 2. Groutine 调度原理 3. Groutine 示例代码 关于Go的底层实现还需要后续持续研究,文中如有一些原理描述有误,欢迎指证. 1 ...

  8. Go 分布式学习利器(14)-- Go语言的错误处理

    1. Go 的错误机制 Go 语言的错误机制中与其他语言的主要差异如下: 没有异常机制 error 类型实现了 error接口 type error interface {Error() string ...

  9. Go 分布式学习利器(13)-- Go语言的多态

    文章目录 1. 基本的多态实现 2. 空接口与断言 3. Go接口的最佳实践 1. 基本的多态实现 我们知道C++中实现多态是通过虚函数表 和 继承来 实现的. 类似如下代码: class Progr ...

最新文章

  1. 图像相似度计算之直方图方法OpenCV实现
  2. 字节跳动教育裁员:赔付方式N+2
  3. 转变矛头,号称攻破BCH网络的Bitpico或与BCE决裂
  4. VC2019消息框编程总结
  5. hdu 3006(状态压缩)
  6. 一个老王开枪案例带你一步一步领略程序开发的魅力
  7. 移动通信蜂窝原理例题整理
  8. 花生采摘(洛谷P1086题题解,Java描述)
  9. UESTC 288 青蛙的约会 扩展GCD
  10. 苹果鼠标怎么充电_双十一苹果无线充电宝怎么选?充电兼容性强的品牌推荐_...
  11. salt一键部署jdk
  12. 安装apache重启的时候,报错端口被占用,错误1
  13. 树莓派摄像头模块(Pi Cam)的安装使用
  14. GNU nano介绍
  15. python自动发邮件运行正常就是收不到邮件是为什么_Python自动化测试发送邮件太麻烦?!一起聊一聊 Python 发送邮件的3种方式...
  16. 软件即服务已经过时 硬件即服务促成云计算
  17. 南京信息工程大学计算机科学与技术评级,晋升ESI排名全球前1‰,南京信息工程大学这个学科不简单!...
  18. 【滤波器】基于matlab实现微波带低通高通带通滤波器设计
  19. 华为鸿蒙OS摄像头,首款华为鸿蒙OS摄像头开售:分布式看家新神器 无需SD卡
  20. “风雨如晦,鸡鸣不已。既见君子,云胡不喜。” 王者荣耀李白王昭君情侣头像故事...

热门文章

  1. Linux 的数字权限意义
  2. sskeychain使用(轻量级框架)
  3. 经典贪心法:时间序列问题及其全局最优性证明
  4. Linux 启动详解之init
  5. WCF学习笔记(二):在WCF中使用集合传输数据
  6. 简单实现ConfigurationManager.AppSettings[]效果存储系统变量
  7. sql server 2005 T-SQL @@TOTAL_READ (Transact-SQL)
  8. SVO中 Inverse Compositional Image Alignment方法的学习笔记
  9. linux安装vsftpt服务,centos安装vsftp服务.md
  10. php excel 追加写入,phpexcel写入追加已有的excel文件