01、type关键字:用于定义函数类型
--函数类型:
--使用type关键字来定义一个函数类型,具体格式如下:
type calculation func(int, int) int
注:上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。
简单来说,凡是满足这个条件的函数都是calculation类型的函数,例如下面的add和sub是calculation类型。
--代码示例01:打印不同返回值和参数的函数类型
func f1() {
}
func f2() int {
return 2
}
func main() {
a := f1
fmt.Printf("%T\n", a)
b := f2
fmt.Printf("%T\n", b)
}
--代码执行结果01:
func()
func() int
02、函数也可以作为参数类型,即定义参数时传递一个函数
--最基本使用:
func f2() int {
return 2
}
func f3(x func() int) { // 传入的参数类型就是func() int
fmt.Println(x())
}
func main() {
f3(f2) // 这里就把f2当作一个参数传入到f3中
}
03、函数还可以作为一个返回值
--函数还可以作为返回值,至此闭包函数的特性全部结束。非常类似于python中的闭包函数
--代码示例:
func f2() (m int, n int) {
return 2, 3
}
func ff(a int, b int) int {
return a + b
}
func f5(x func() (int, int)) (fa func(int, int) int) {
// f5参数输入值为函数类型:func() int 类型 -- 该函数没有参数,返回值为int类型
// 返回值类型为函数类型:func(int, int)int -- 该函数参数为两个int int,返回值为int
// go语言尽管不允许嵌套申明,但允许嵌套调用且可以在调用时定义匿名函数
// func printyh()(){} 这种直接定义没有函数接收是不允许的
// v1 := func()(){*** ***} 但是匿名函数是合法的
// a, b := x()
return ff
}
func main() {
ref := f5(f2) // 这里就把f2当作一个参数传入到f3中
fmt.Printf("%T\n", ref) // func(int, int) int
fmt.Println(ref) // 0x887280
}
04、匿名函数定义和使用
--匿名函数:没有名称呗,基本格式:
func(参数 类型,参数 类型, ...)(返回值 类型,返回值 类型){
函数体
}
--一般定义在函数体内,因为函数体外正常定义就好了不需要使用匿名函数
--代码示例如下:
func main() {
// 匿名函数使用01:先定义后调用,{}后面不带()
f1 := func(x, y int) {
fmt.Println(x + y)
}
f1(2, 3)
// 匿名函数使用02:定义并同时调用,也就是直接传参。如果没有参数也要加一个()
func(x, y int) {
fmt.Println(x + y)
}(100, 200)
}
05、闭包函数 -- 初始例子讲解
--代码示例如下:
--f1展示了如何闭包传递一个无参数函数
--f3展示了如何闭包传递一个有参函数
--f2则是那个被传递的函数
func f1(f func()) {
fmt.Println("this is f1")
f()
}
func f2(x, y int) {
fmt.Println("this is f2")
fmt.Println(x + y)
}
// f3才是展示了如何把带参数函数传递到闭包中
// f1无法传递
func f3(x func(int, int), m, n int) func() {
tmp := func() { // 定义一个匿名函数
x(m, n)
}
return tmp // 执行匿名函数
}
func main() {
// 现在就让把 f2传入f1即可
// f1(f2) 是存在问题的不允许这么直接传
f3(f2, 100, 300)() // 这里返回函数需要加一个()来执行才行
}
06、深入各种闭包编程
--闭包编程实例01: