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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值