Go学习笔记 -- 函数和高阶函数
admin
2024-02-03 12:34:24

文章目录

    • Go 函数
      • 定义函数
      • 函数特性
        • 支持不定参
        • 支持多返回值和命名返回参数
        • 不支持嵌套,不支持重载
      • 高阶函数
      • 闭包
        • 什么是闭包
        • 用代码来解释
        • 闭包的作用

Go 函数

定义函数

使用 func 关键词,第一个括号里面定义参数类型以及参数的标识符,第二个括号里面定义返回值类型。

func print(contents string) (int, error) {//打印字符串并返回打印的字节数。return fmt.Println(contents)
}

函数特性

  • 支持不定参。
  • 支持多返回值。
  • 支持命名返回参数。
  • 不支持嵌套,同一个包内不能有两个相同名字的函数。
  • 不支持重载。
  • 不支默认参数。
  • 在 Go 中,函数也是一种类型,可以作为方法的入参或者返回结果。
  • 支持匿名函数和闭包。

其中先简单了解一下基本的特性。

支持不定参

如下,print 函数有一个可以接受多个 string 入参。
JAVA 里面的不定参类似,这其实相当于是接受一个 srting 类型的数组,但是这样的入参类型只能定义在函数的最后面。

func print(contents ...string) (int, error) {//打印字符串并返回打印的字节数。return fmt.Println(contents)
}
func main() {fmt.Println(print("11", "22"))
}
------------------------------------------------------
[11 22]
8 

支持多返回值和命名返回参数

上面的例子就是一个多返回值的函数,同时我们还能命名函数返回值。
返回的时候直接用 retun ,函数会自动将 counterr 返回回去。

func print(contents ...string) (count int, err error) {//接收打印的字节数和异常count,err = fmt.Println(contents) return
}
func main() {fmt.Println(print("11", "22"))
}
------------------------------------------------------
[11 22]
8 

不支持嵌套,不支持重载

以下代码都提示异常
文件①:/demo/demo_lib1.go

package main
import ("fmt"
)
//提示异常: other declaration of print
func print(sss int, contents ...string) (count int, err error) {//打印字符串并返回打印的字节数。count, err = fmt.Println(contents)return
}

文件②:/demo/demo_main.go

package main
import ("fmt"
)
//提示异常: other declaration of print
func print(contents ...string) (count int, err error) {//打印字符串并返回打印的字节数。count, err = fmt.Println(contents)return
}
func main() {fmt.Println(print2("11", "22"))
}

高阶函数

上面我们提到,在 Go 中,函数可以作为另一个函数的入参或者返回结果。而以函数作为参数或者返回值的函数就称为高阶函数。
高阶函数的条件,满足其一即可:

  1. 使用其他函数作为入参
  2. 把其他函数作为返回结果

例如:
下面的 calc 函数和 retFunc 函数都是高阶函数。

type mathFunc func(x, y int) intfunc calc(x int, y int, mf mathFunc) (int, error) {if mf == nil {return 0, errors.New("invalid operation")}return mf(x, y), nil
}func retFunc() mathFunc {return func(x, y int) int {return x + y}
}

闭包

什么是闭包

闭包是可以包含自由变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块为自由变量提供绑定的作用域。

用代码来解释

type mathFunc func(i int) int
func operate2() mathFunc {sum := 0return func(j int) int {sum += jreturn sum }
}

其中 operate2 函数中返回的这个匿名函数,就形成了一个闭包。
闭包中使用到了自由变量 sum ,这个 sum 是闭包函数所处函数环境中定义的,可以说匿名函数的功能被绑定在了变量 sum 上。

addBase := operate2(1) //addBase 为所有传入的 int 加 1
fmt.Println(addBase(2))
-----------------------------
3

闭包的作用

  1. 延迟动态生成程序逻辑,我们可以根据需要生成功能不同的函数。
  2. 缩小变量作用域,减少对全局变量的污染
    在上面的例子中,我们其实实现了一个累加器,如果我们定义的是全局变量 sum ,有可能会被其他操作污染,而且当我们需要实现很多个累加器时,我们就需要定义很多个全局变量 sum 1…n
    但是我们使用闭包的方式,将累加值定义在函数中,缩小其作用域,使每个函数有自己独立的累加值,避免了累加值被其他操作污染的情况。

相关内容

热门资讯

随笔|我把芫荽炒成菜 文|臧彦钧 馋人多半喜欢自己下厨。除了自己动手不用求人外,更多的是能在烹饪过程中自由发挥,抛开前人的...
4分钱的壳配3毛钱的肉?不少成... 对于热爱美食的当地人来说 在夜市或者美食街 都看到过这种“流量食物” ——蒜蓉粉丝烤扇贝 而且价格还...
全国首个以宋词为核心主题的演艺... 齐鲁晚报·齐鲁壹点 张浩穿越回李清照的时代与其展开时空对话,化身为玩家体验真实宋代生活……近日,在济...
“全球文旅轻创业计划”在京发布... 2025年11月17日上午,“银发文旅项目发布会暨全球文旅轻创业计划启动仪式”在中国传媒大学成功举办...
城事|办理口岸过百,台湾“首来... 据央视新闻消息,19日,国台办举行例行发布会,大陆持续释放旅游福利,首次来大陆的台胞“首来族”可获得...