将函数(或方法)作为参数传入

package main

import "fmt"

func add(num1 int64, num2 int64) (result int64) {
   result = num1 + num2
   return
}

func sub(num1 int64, num2 int64) (result int64) {
   result = num1 - num2
   return
}

// calculate1
// @description 计算
// @param function func(int64, int64) int64 函数,该函数有两个形参(数据类型均为int64),返回值为int64数据类型
// @param num1 int64 操作数1
// @param num2 int64 操作数2
// @return result int64 计算结果
func calculate1(function func(int64, int64) int64, num1 int64, num2 int64) (result int64) {
   result = function(num1, num2)
   return
}

// calculate2
// @description 计算
// @param function any 函数,由于是any类型所以不能直接调用,需要断言才能调用
// @param num1 int64 操作数1
// @param num2 int64 操作数2
// @return result int64 计算结果
func calculate2(function any, num1 int64, num2 int64) (result int64) {
   // 断言形参function是一个函数,该函数有两个形参(数据类型均为int64),返回值为int64数据类型
   f, ok := function.(func(int64, int64) int64)
   if ok {
      // 断言成功就可以调用了
      result = f(num1, num2)
   }

   return
}

func main() {
   // 把add()函数作为参数
   resultAdd := calculate1(add, 5, 2)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 7

   // 把sub()函数作为参数
   resultSub := calculate1(sub, 5, 2)
   fmt.Printf("resultSub => %+v \n", resultSub) // resultSub => 3

   // 把add()函数作为参数
   resultAdd = calculate2(add, 7, 3)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 10

   // 把sub()函数作为参数
   resultSub = calculate2(sub, 7, 3)
   fmt.Printf("resultSub => %+v \n", resultSub) // resultSub => 4
}

// ========== 总结 ========== //
// 1、Go语言允许把一个函数作为参数传入,由于Go语言是强类型语言,所以想调用这个函数必须明确知道其形参和返回值,
//    这样一来就有两种方式实现,具体实现代码可看calculate1()函数和calculate2()函数。



package main

import "fmt"

type calculate struct {
}

func (cal *calculate) add(num1 int64, num2 int64) (result int64) {
   result = num1 + num2
   return
}

func (cal *calculate) sub(num1 int64, num2 int64) (result int64) {
   result = num1 - num2
   return
}

func test1(function func(int64, int64) int64, num1 int64, num2 int64) (result int64) {
   result = function(num1, num2)
   return
}

func test2(function any, num1 int64, num2 int64) (result int64) {
   f, ok := function.(func(int64, int64) int64)
   if ok {
      result = f(num1, num2)
   }

   return
}

func main() {
   cal := &calculate{}

   resultAdd := test1(cal.add, 5, 2)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 7

   resultSub := test1(cal.sub, 5, 2)
   fmt.Printf("resultSub => %+v \n", resultSub) // resultSub => 3

   resultAdd = test2(cal.add, 5, 2)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 7

   resultSub = test2(cal.sub, 5, 2)
   fmt.Printf("resultSub => %+v \n", resultSub) // resultSub => 3

   // 闭包(匿名函数内部使用了外部变量cal)
   closureAdd := func(num1 int64, num2 int64) (result int64) {
      result = cal.add(num1, num2)
      return
   }

   resultAdd = test1(closureAdd, 10, 24)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 34

   resultAdd = test2(closureAdd, 10, 24)
   fmt.Printf("resultAdd => %+v \n", resultAdd) // resultAdd => 34
}

// ========== 总结 ========== //
// 1、将方法作为参数传入和将函数作为参数传入基本是一样的,不过方法多了一种闭包的方式。

Copyright © 2024 码农人生. All Rights Reserved