Golang 如何将一个函数作为另一个函数的输入值,清晰透彻的注释让你理解该如何阅读抽象的代码

package main

import (
"fmt"
"reflect"
"time"
)

//输入参数是个函参且函参函数没有输入参数
func GoFunc1(f func()) {
go f()
}

//输入参数第1个是个函参且函参函数只有1个接口型输入值,第2参数是函参函数的输入参数
func GoFunc2(f func(interface{}),i interface{}) {
go f(i)
}

//输入参数第1个是接口参数类型,第2个输入参数是变参类型
func GoFunc3(i interface{},args ...interface{}) {
if len(args) > 1 {
//接口 i 调用函数格式满足func(...interface{}),输入参数格式是变参类型,那么满足这样条件的函数只有f3符合
go i.(func(...interface{}))(args)
} else if len(args) == 1 {
//接口 i 调用函数格式满足func(interface{}),输入参数格式只有1个接口类型,那么满足这样条件的函数只有f2符合
go i.(func(interface{}))(args[0])
} else {
//接口 i 调用函数格式满足func(),没有输入参数的格式,那么满足这样条件的函数只有f1符合
go i.(func())()
}
}

//没有输入参数的函数
func f1() {
fmt.Println("f1 has been run completely.")
}

//输入参数是只有1个接口的函数
func f2(i interface{}) {
//多选语句switch要先知到它是几个类型中的一个,i.(type)只能在switch中使用,这函数没有返回值
switch i.(type) {
case string:
//是字符时做的事情
fmt.Println(i," is type of string in f2")
case int:
//是整数时做的事情
fmt.Println(i," is type of int in f2")
default:
fmt.Println("无法识别类型:",i) //例如输入1个布尔值
}
//反射这个方法可以对任意对象使用
fmt.Println("f2 has been run completely,",i,"真实的对象类型:",reflect.TypeOf(i))
}

//变参函数是参数个数和类型都不确定的函数
func f3(args ...interface{}) {
fmt.Println("f3 has been run completely,"args length = ",len(args),args[0] = ",args[0],args[0] Type = ",reflect.TypeOf(args[0]))
for _,arg := range args[0].([]interface{}) {
switch v := arg.(type) {
case int:
fmt.Println(v," is type of int in f3")
case int32:
fmt.Println(v," is type of int32 in f3")
case int64:
fmt.Println(v," is type of int64 in f3")
case bool:
fmt.Println(v," is type of bool in f3")
case string:
fmt.Println(v," is type of string in f3")
case float32:
fmt.Println(v," is type of float32 in f3")
case float64:
fmt.Println(v," is type of float64 in f3")
default:
fmt.Println(v," data type has been not yet supported,reflect.TypeOf = ",reflect.TypeOf(v)," in f3")
}
}
fmt.Println("===================================================================")
for _,arg := range args[0].([]interface{}) {
fmt.Println("Value = ",arg," reflect.TypeOf = ",reflect.TypeOf(arg)," in f3")
}
fmt.Println("===================================================================")
}

func main() {

GoFunc3(f3,"moxi","moxi?",19861206,3.1415927)

GoFunc1(f1)
GoFunc2(f2,1<<20)
GoFunc3(f1)
GoFunc3(f2,"So in Love")
GoFunc3(f2,true)
//阻塞主进程5秒后结束,也就是所有的协程只有5秒代码的执行时间,
//不管这些协程有没有处理完工作,将退出整个程序
time.Sleep(500 * time.Second)

}


调试控制台打印输出如下信息:

2017/07/01 12:49:13 server.go:73: Using API v1 2017/07/01 12:49:13 debugger.go:97: launching process with args: [/root/code/go/src/contoso.org/book/debug] API server listening at: 127.0.0.1:2345 2017/07/01 12:49:13 debugger.go:505: continuing f3 has been run completely,args length = 1,args[0] = [moxi moxi? 19861206 3.1415927],args[0] Type = []interface {} moxi is type of string in f3 moxi? is type of string in f3 19861206 is type of int in f3 3.1415927 is type of float64 in f3 =================================================================== Value = moxi reflect.TypeOf = string in f3 Value = moxi? reflect.TypeOf = string in f3 Value = 19861206 reflect.TypeOf = int in f3 Value = 3.1415927 reflect.TypeOf = float64 in f3 =================================================================== f1 has been run completely. 1048576 is type of int in f2 f2 has been run completely,1048576 真实的对象类型: int f1 has been run completely. So in Love is type of string in f2 f2 has been run completely,So in Love 真实的对象类型: string 无法识别类型: true f2 has been run completely,true 真实的对象类型: bool

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...