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 <nil>
支持多返回值和命名返回参数

上面的例子就是一个多返回值的函数,同时我们还能命名函数返回值。
返回的时候直接用 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 <nil>
不支持嵌套,不支持重载

以下代码都提示异常
文件①:/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) int

func 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 := 0
	return func(j int) int {
		sum += j
		return sum 
	}
}

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

addBase := operate2(1) //addBase 为所有传入的 int 加 1
fmt.Println(addBase(2))
-----------------------------
3
闭包的作用
  1. 延迟动态生成程序逻辑,我们可以根据需要生成功能不同的函数。
  2. 缩小变量作用域,减少对全局变量的污染
    在上面的例子中,我们其实实现了一个累加器,如果我们定义的是全局变量 sum ,有可能会被其他操作污染,而且当我们需要实现很多个累加器时,我们就需要定义很多个全局变量 sum 1…n
    但是我们使用闭包的方式,将累加值定义在函数中,缩小其作用域,使每个函数有自己独立的累加值,避免了累加值被其他操作污染的情况。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mingvvv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值