go语法入门-将函数作为函数的参数(回调函数)

茧型元组
• 阅读 1277

一、介绍。

go语言的函数参数,一般我们常用的是,一个实际的值,比如 int,或者struct,map,指针等。
但在一些高阶的用法中,常见函数,作为参数,比如net/http库等。今天我们学一下如何使用函数作为函数的参数。

回调函数

被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。 以上示例为同步回调,它是立即执行的。 然而需要注意的是,回调函数经常被用于在一个异步操作完成后执行代码,它们被称为异步回调

二、入门使用。

回调函数其实说白了,函数为参数,被另一个函数使用。就是函数调用函数
我们在一个函数内,调用另外一个函数。

2.1 使用一个 最简单的 无参,无返回函数。

在这里,我们参数为printOne()或printTwo()。
我们在funcNoParam中使用它。

func printOne() {
    fmt.Println("one")
}

func printTwo() {
    fmt.Println("two")
}

func funcNoParam(f func()) {
    f()
}

func TestFuncNoParam(t *testing.T) {
    funcNoParam(printOne)
    funcNoParam(printTwo)
}

在上面的示例中,我们使用printOne以及printTwo 作为 funcNoParam的参数。
执行完结果为:

=== RUN   TestFuncNoParam
one
two
--- PASS: TestFuncNoParam (0.00s)

可以只要符合func(),我们就可以传进到funcNoParam(f func())中。
可以执行无数种函数调用。

2.2 调用一个有参函数

在这里printOneParam(p int),printOnePlus(p int),都是为一个参数的函数。

printOneParam(p int) 为直接打印出一个p值
printOnePlus(p int) 为打印出一个 p++值

我们使用funcParamOne(f func(a int))来把他们作为一个参数传进来,供自己调用。

func printOneParam(p int) {
    fmt.Println(p)
}

func printOnePlus(p int) {
    fmt.Println(p + 1)
}

func funcParamOne(f func(a int)) {
    num := 100
    f(num)
}

func TestFuncParamOne(t *testing.T) {
    funcParamOne(printOneParam)
    funcParamOne(printOnePlus)
}

在这里,我们定义了一个函数funcParamOne(f func(a int))它的参数是一个带有一个int参数的函数,我们在funcParamOne调用了f。
然后我们我们调用了两个符合 func(a int)类型的函数,printOneParam以及printOnePlus。
结果为:

=== RUN   TestFuncParamOne
100
101
--- PASS: TestFuncParamOne (0.00s)

2.3 调用一个有返回值函数

func funcInt64(f func() int64) string {
    return fmt.Sprintf("string之为: %d", f())
}

func TestFuncInt64(t *testing.T) {
    t.Log(funcInt64(rand.Int63))
    t.Log(funcInt64(time.Now().Unix))
}

在这里,我们调用了rand.Int63(),以及 time.Now().Unix()
输出结果:

=== RUN   TestFuncInt64
    string之为: 5577006791947779410
    string之为: 1676257027
--- PASS: TestFuncInt64 (0.00s)

注意,我们调用函数的时候,都没有加上(),是因为在里面我们加上了括号,不然就两个括号了。

2.4 一个函数,一个变量,两个参数

func ReduceNUm(base int, num int) {
    fmt.Printf("%d减少%d后为:%d\n", base, num, base-num)
}

func AddNum(base, num int) {
    fmt.Printf("%d加上%d后为:%d\n", base, num, base+num)
}

func callback(base int, f func(int, int)) {
    f(base, 5) // 减少或者加上5
}

func TestCallback(t *testing.T) {
    callback(100, ReduceNUm)
    callback(100, AddNum)
}

输出:

=== RUN   TestCallback
100减少5后为:95
100加上5后为:105
--- PASS: TestCallback (0.00s)
点赞
收藏
评论区
推荐文章
晴空闲云 晴空闲云
3年前
JavaScript中MutationObServer监听DOM元素详解
DOM的MutationObServer接口,可以在DOM被修改时异步执行回调函数,我的理解就是可以监听DOM修改。基本使用可以通过MutationObserver构造函数实例化,参数是一个回调函数。jsletobservernewMutationObserver(()console.log("change"));console.log(obs
Souleigh ✨ Souleigh ✨
4年前
初识 JS 中的柯里化
作为函数式编程语言,JS带来了很多语言上的有趣特性,比如柯里化。1.简介柯里化(Currying),又称部分求值(PartialEvaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。核心思想是把多参数传入的函数拆成单参数(或部分)函
菜园前端 菜园前端
2年前
什么是高阶函数?
原文链接:什么是高阶函数?有两种情况都可以被定义为高阶函数,第一种是把函数作为参数传递给另外一个函数,第二种是把函数作为另一个函数的返回结果。就像我们平时调用函数,一般都是传递值类型或者对象和数组等参数,或者是函数返回结果是值类型或者是对象和数组,高阶函数
菜园前端 菜园前端
2年前
什么是回调函数?
原文链接:什么是回调函数?简单的来说,一个函数作为另外一个函数的参数,可以称为回调函数。这个理解其实不完全对,回调的意义根本没有体现出来,何为回调?也就是说一个函数你定义了,你没有马上的去调用它,而是交给了另外一个函数去调用,这才属于回调函数。缺点直接使用
Stella981 Stella981
3年前
AVIOInterruptCB结构体分析
1AVIOInterruptCB结构体定义在/usr/include/libavformat/avio.h中有如下的结构体定义,根据头文件中的注释:这是一个回调函数和参数的结构体。有些函数是在阻塞的,用这个回调函数来检查是否中断这个阻塞函数,如果回调函数返回1,那么这个正在阻塞的操作将被中止。那么就用这个结构体里的参数opaque来回调其中的callb
Stella981 Stella981
3年前
Python进阶
python高阶函数可以接受函数作为参数的函数defadd(x,y,f):   returnf(x)f(y)由于参数想,x,y和f都可以任意传入,如果f传入其他函数,就可以得到不同的返回值map()函数它接收一个函数f和一个list,并通过把函数f依次作用在list的每
Stella981 Stella981
3年前
JavaScript回调函数的高手指南
摘要:本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。回调函数是每个前端程序员都应该知道的概念之一。回调可用于数组、计时器函数、promise、事件处理中。本文将会解释回调函数的概念,同时帮你区分两种回调:同步和异步。1.回调函数首先写一个向人打招呼的函数。只需要创建一个接受name参数的函数gree
Stella981 Stella981
3年前
ES6 Promise 对象扯谈
newPromise(/executor/function(resolve,reject){...});Promise的构造函数接收一个函数作为参数,函数里面传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。其实这里用“成功”和“失败”来描述并不准确,按照标准来
Stella981 Stella981
3年前
26 函数形参值回传问题——C++解决多个return的一般方法
0引言在使用数组和vector作为函数的参数进行参数传递并希望得到值的回传时,由于不知道怎么写数组函数形参的引用形式,一直采用vector的引用形式。但是,刚刚测试了一下,发现数组作为参数本身就是指针,根本不需要采用引用形式把值回传啊,把测试结果写下来。1 关于数组作为函数参数的值传递问题——数组和容器的对比  数组直接作为
Stella981 Stella981
3年前
Golang可变参数
Go可变参数语法如果一个函数最后一个参数被标记为…T,表示函数可以接受一个可变的参数。比如,我们想在nums中查找num是否存在:funcfind(numint,nums…int){}目的是通过find函数,在nums中查找num。比如:find(89,89,90
Wesley13 Wesley13
3年前
PHP匿名函数及闭包
匿名函数在编程语言中出现的比较早,最早出现在Lisp语言中,随后很多的编程语言都开始有这个功能了,目前使用比较广泛的Javascript以及C,PHP直到5.3才开始真正支持匿名函数,C的新标准C0x也开始支持了。匿名函数是一类不需要指定标示符,而又可以被调用的函数或子例程,匿名函数可以方便的作为参数传递给其他函数,最常见应用是作为回调函数