go中函数在Go语言中属于“一等公民”,说白了就是可以把函数当变量一样去用,具体如下
1、可以声明函数类型的变量
2、可以赋值
3、可以当做另外一个函数的参数
4、可以当做另外一个函数的返回值
了解:高阶函数指的就是
1、函数可以作为参数
2、函数可以作为返回值
我们可以使用type
关键字来定义一个函数类型,具体格式如下:
| type calculation func(int,int) int |
上面语句定义了一个calculation
类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值,凡是满足该条件的函数都是calculation类型的函数,如下add和sub
| func add(x, y int) int{ |
| return x + y |
| } |
| func sub(x, y int) int{ |
| return x - y |
| } |
| |
| func main() { |
| fmt.Printf("%T\n",add) |
| fmt.Printf("%T\n",sub) |
| } |
可以把函数赋值变量,前提是该变量是对应的函数类型
| func main() { |
| var c calculation |
| c = add |
| fmt.Printf("%T\n", c) |
| fmt.Println(c(1, 2)) |
| |
| f := add |
| fmt.Printf("%T\n", f) |
| fmt.Println(f(10, 20)) |
| } |
注意:
函数的类型被称为函数的标识符。如果两个函数形式参数列表和返回值列表中的变量类型一一对应,那么这两个函数被认为有相同的类型和标识符。形参和返回值的变量名不影响函数标识符,也不影响它们是否可以以省略参数类型的形式表示。
| |
| func test1(x int, y int) (z float64) { |
| fmt.Println(x,y) |
| return 1.1 |
| } |
| |
| func test2(xxx int, yyy int) (zzz float64) { |
| fmt.Println(xxx,yyy) |
| return 1.1 |
| } |
| |
| func main() { |
| fmt.Printf("%T\n",test1) |
| fmt.Printf("%T\n",test2) |
| |
| var f func(int, int) float64 |
| f = test1 |
| f(1,2) |
| |
| f=test2 |
| f(10,20) |
| } |
| type calculation func(int, int) int |
| |
| func add(x, y int) int { |
| return x + y |
| } |
| func cal1(x, y int, op calculation) int { |
| return op(x, y) |
| } |
| |
| func cal2(x, y int, op func(x, y int) int) int { |
| return op(x, y) |
| } |
| |
| func main() { |
| res1 := cal1(10, 20, add) |
| fmt.Println(res1) |
| |
| res2 := cal1(10, 20, add) |
| fmt.Println(res2) |
| } |
| func do(s string) (func(int, int) int, error) { |
| switch s { |
| case "+": |
| return add, nil |
| case "-": |
| return sub, nil |
| default: |
| err := errors.New("无法识别的运算符") |
| return nil, err |
| } |
| } |
| |
| func main() { |
| f,err:=do("-") |
| fmt.Println(f,err) |
| fmt.Println(f(111,222)) |
| } |
基于函数是第一等公民这一特性,优雅地取代多分支if
| func login() { |
| fmt.Println("要想生活过得去,身上必须背点绿") |
| } |
| func register() { |
| fmt.Println("要想生活过得好,头顶必须长点草") |
| } |
| func withdraw() { |
| fmt.Println("横批:绿毛小乌龟") |
| } |
| |
| var funcSlice map[string]func()= map[string]func(){ |
| "登录":login, |
| "注册":register, |
| "提现":withdraw, |
| } |
| |
| func main() { |
| |
| var fname string |
| fmt.Printf("请输入功能名: ") |
| fmt.Scanln(&fname) |
| |
| f,ok:=funcSlice[fname] |
| if ok{ |
| f() |
| }else { |
| fmt.Println("输入的功能不存在") |
| } |
| } |