红酒泡绿茶 2018-09-12 15:13
浏览 47
已采纳

映射以在Go中存储泛型类型函数

I am trying to create a Map with String and functions as key and Value. It works if all functions are of same signature but my requirement is to store functions of different signature in the same map. Is this possible in Go?

package main

import "fmt"

func main() {

    functions := buildFunctions()
    f := functions["isInValid"]

    //  f("hello")

}

func buildFunctions() map[string]func() bool {

    functions := map[string]func() bool{
        "isInValid":   isInValid,
        "isAvailable": isAvailable,
    }
    return functions
}

func isInValid(s string) bool {
    fmt.Println("Invalid ", s)
    return true
}

func isAvailable(s string, s1 string) bool {
    return true
}

https://play.golang.org/p/ocwCgEpa_0G

  • 写回答

1条回答 默认 最新

  • dongmu3269 2018-09-12 16:04
    关注

    Go is a strongly typed language. So, it's not possible the way, it is possible with, say python. But just like python, once you do this, you loose the benefit of compile time error checks, and your runtime error checking has to be full-proof. Here's what you can do:

    1. Use map[string]interface{} type for your function map, which enables you to store anything. But then you are responsible to correctly type assertion at the time of calling. Problem is that, in most cases, if while calling a function, you could know the type of function, may be you might not need a map in the first place.

    2. Use a map[string]string or map[string]interface{} as the argument, and return type in all the functions that are supposed to go into this map. Or at least put all the variable arguments into this map.

      eg.

      map[string](func (name string, age int, other_attributes map[string]interface{}) (map[string]interface{}, error))

    But again, each function call should provide the correct arguments, and there should also be checks inside the functions, to see (with non-panic version of map lookup), if the parameters are correctly provided, if not, you can return a custom error like ErrInvalidParametersPassed. (playing the role of an interpreter). But you will still have lesser chances of messing up, compared to first option. As the burden of type assertion will be on the function implementation, and not the caller. Caller just needs to fetch it's required values, which it anyways needs to know about.

    But yet, best option would be to redesign your actual solution in a way, so that it can be done without going this road. As @bereal suggested in comments, it's good to have separate maps if possible, or maybe use a superset of arguments if they aren't too different, or too many. If there are just a few arguments, even switch case could be clean enough. Look for ways that cheat/bypass compile time checks, when you are truly convinced that there is no other elegant way.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题