go 函数类型

函数类型
函数的名字表示一个地址,函数在代码区的地址

package main
import "fmt"
func demo(a int, b int) {
   fmt.Println(a + b)
}
func main() {
   demo(10, 20)
   fmt.Println(demo) //0x2cb460  默认打印的是一个代码区的地址
   //f是func(int, int)函数类型定义的变量
   //f := demo
   var f func(int, int)
   f = demo

   fmt.Println(f) //0x2cb460  代码区的内存地址
   //通过f调用函数
   f(10, 20)
   fmt.Printf("%T", f) //func(int, int)  
}

在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。

func demo(a int, b int) {
	fmt.Println(a + b)
}
func demo2(x int, y int) {
	fmt.Println(x - y)
}
func main() {
	//f := demo
	var f func(int, int)
	f = demo
	f = demo2//不报错
	f(1, 2)

}

注意:当定义好函数类型的时候格式就确定了,如果是新的格式就不行

package main

import "fmt"

//func(int, int)
func demo(a int, b int) {
	fmt.Println(a + b)
}

//func(int, int) int
func demo2(x int, y int) int {
	return x + y
}
func main() {
	//f := demo
	var f func(int, int)
	f = demo
	f = demo2 //err报错
	fmt.Printf("%T", f)
}

为了简化数据类型定义,Go支持自定义数据类型

基本语法: type 自定义数据类型名 数据类型

可以理解为 : 相当于起了一个别名。如果我们在很多程序中定义这样的格式,取别名在使用可以更方便一点。

package main

import "fmt"

//func(int, int)
func demo(a int, b int) {
	fmt.Println(a + b)
}

//func(int, int) int
func demo2(x int, y int) int {
	return x + y
}

//定义函数类型 为已存在的数据类型起别名
type FUNCDEMO func(int, int)

func main() {
	var f FUNCDEMO
	f = demo
	fmt.Printf("%T", f)//main.FUNCDEMO
}

函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用(把函数本身当做一种数据类型)

package main
import "fmt"
//定义一个函数:
func test(num int){
        fmt.Println(num)
}
//定义一个函数,把另一个函数作为形参:
func test02 (num1 int ,num2 float32, testFunc func(int)){
        fmt.Println("-----test02")
}
func main(){
        //函数也是一种数据类型,可以赋值给一个变量	
        a := test//变量就是一个函数类型的变量
        fmt.Printf("a的类型是:%T,test函数的类型是:%T \n",a,test)//a的类型是:func(int),test函数的类型是:func(int)
        //通过该变量可以对函数调用
        a(10) //等价于  test(10)
        //调用test02函数:
        test02(10,3.19,test)
        test02(10,3.19,a)
}