go 语言回调函数和闭包

简介: go 语言回调函数和闭包

Go基础系列:函数(2)——回调函数和闭包 - 骏马金龙 - 博客园 (cnblogs.com)

当函数具备以下两种特性的时候,就可以称之为高阶函数(high order functions):

  1. 函数可以作为另一个函数的参数(典型用法是回调函数)
  2. 函数可以返回另一个函数,即让另一个函数作为这个函数的返回值(典型用法是闭包)

一般来说,附带的还具备一个特性:函数可以作为一个值赋值给变量。

由于Go中函数不能嵌套命名函数,所以函数返回函数的时候,只能返回匿名函数。

在Go语言中,回调函数和闭包都是函数式编程的重要概念,它们都可以用于在函数间传递和操作函数。下面分别介绍一下回调函数和闭包在Go语言中的概念和用法:

回调函数(Callback Functions):

回调函数是指作为参数传递给其他函数的函数。在Go语言中,函数和变量的地位相同,是一等公民,因此可以像其他数据类型一样作为参数传递给函数。通过使用回调函数,可以在函数内部调用外部定义的函数,实现更灵活和可复用的代码结构。

示例:

go

复制代码

package main
import "fmt"
// 回调函数,接收一个int类型参数并返回一个int类型结果
func callbackFunc(x int) int {
    return x * x
}
// 函数f接收一个int类型参数和一个函数类型参数,函数类型参数的类型是func(int) int
func f(y int, callback func(int) int) int {
    return callback(y) // 调用传入的回调函数
}
func main() {
    result := f(3, callbackFunc) // 将callbackFunc作为回调函数传递给函数f
    fmt.Println(result) // 输出结果:9
}

使用回调函数实现类似函数重载的效果

在Go的sort包中有一个很强大的Slice排序工具SliceStable(),它就是将排序函数作为参数的:

go

复制代码

func SliceStable(slice interface{}, less func(i, j int) bool)

less 作为一个回调函数,把 i,j 作为slice中的下标,返回比较结果,和 C++ 中的 sort 类似

闭包(Closure):

闭包是指在函数内部定义的函数,它可以访问其外部函数中的变量。在Go语言中,闭包可以帮助我们实现类似于函数式编程的一些特性,如函数柯里化、延迟执行等。

闭包中的变量被分配到堆上。

示例:

go

复制代码

package main
import "fmt"
// 函数返回一个函数,内部的函数形成了闭包,可以访问外部函数的变量x
func adder(x int) func(int) int {
    return func(y int) int {
        return x + y
    }
}
func main() {
    // 使用闭包创建一个加法器函数
    addTwo := adder(2)
    // 使用闭包创建一个减法器函数
    subtractFive := adder(-5)
    // 调用加法器函数
    fmt.Println(addTwo(3)) // 输出结果:5 (2+3)
    // 调用减法器函数
    fmt.Println(subtractFive(10)) // 输出结果:5 (-5+10)
}

在这个示例中,adder函数返回一个闭包,闭包可以访问外部函数中的变量x,从而实现了对外部变量的“捕获”。闭包addTwosubtractFive分别是加法器和减法器函数,它们可以分别执行加法和减法操作。

总的来说,回调函数和闭包是Go语言中非常常用的函数式编程的概念,它们都能够实现函数间的灵活传递和操作,使得代码更加灵活和可复用


相关文章
|
6天前
|
JSON 测试技术 Go
零值在go语言和初始化数据
【7月更文挑战第10天】本文介绍在Go语言中如何初始化数据,未初始化的变量会有对应的零值:bool为`false`,int为`0`,byte和string为空,pointer、function、interface及channel为`nil`,slice和map也为`nil`。。本文档作为指南,帮助理解Go的数据结构和正确使用它们。
53 22
零值在go语言和初始化数据
|
8天前
|
安全 算法 程序员
在go语言中使用泛型和反射
【7月更文挑战第8天】本文介绍go支持泛型后,提升了代码复用,如操作切片、映射、通道的函数,以及自定义数据结构。 泛型适用于通用数据结构和函数,减少接口使用和类型断言。
69 1
在go语言中使用泛型和反射
|
10天前
|
缓存 编译器 Shell
回顾go语言基础中一些特别的概念
【7月更文挑战第6天】本文介绍Go语言基础涵盖包声明、导入、函数、变量、语句和表达式以及注释。零值可用类型如切片、互斥锁和缓冲,支持预分配容量以优化性能。
41 2
回顾go语言基础中一些特别的概念
|
14天前
|
存储 Go API
一个go语言编码的例子
【7月更文挑战第2天】本文介绍Go语言使用Unicode字符集和UTF-8编码。Go中,`unicode/utf8`包处理编码转换,如`EncodeRune`和`DecodeRune`。`golang.org/x/text`库支持更多编码转换,如GBK到UTF-8。编码规则覆盖7位至21位的不同长度码点。
117 1
一个go语言编码的例子
|
17天前
|
JSON 算法 测试技术
在go语言中调试程序
【6月更文挑战第29天】Go语言内置`testing`包支持单元测试、基准测试和模糊测试。`go test`命令可执行测试,如`-run`选择特定测试,`-bench`运行基准测试,`-fuzz`进行模糊测试。
37 2
在go语言中调试程序
|
7天前
|
JSON Java Go
Go 语言性能优化技巧
在Go语言中优化性能涉及数字字符串转换(如用`strconv.Itoa()`代替`fmt.Sprintf()`)、避免不必要的字符串到字节切片转换、预分配切片容量、使用`strings.Builder`拼接、有效利用并发(`goroutine`和`sync.WaitGroup`)、减少内存分配、对象重用(`sync.Pool`)、无锁编程、I/O缓冲、正则预编译和选择高效的序列化方法。这些策略能显著提升代码执行效率和系统资源利用率。
43 13
|
2天前
|
Cloud Native Java Go
为什么要学习Go语言?
GO logo的核心理念,即简单胜于复杂。使用现代斜体无衬线字体与三条简单的运动线相结合,形成一个类似于快速运动的两个轮子的标记,传达速度和效率。字母的圆形暗示了GO地鼠的眼睛,创造了一个熟悉的形状,让标记和吉祥物很好地搭配在一起。
15 4
|
7天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
41 8
|
8天前
|
前端开发 JavaScript Go
|
6天前
|
存储 Go
go语言中fmt格式化包和内置函数汇总
【7月更文挑战第10天】本文介绍fmt包和`Errorf`用于创建格式化的错误消息。`fmt`包还涉及一些接口,如`Formatter`、`GoStringer`、`ScanState`、`Scanner`和`Stringer`,支持自定义格式化和输入/输出处理。
17 1