dongyingdao8867 2018-10-10 10:37
浏览 367

Golang中的字符串和通用函数的映射

I'm trying to create a map that will map strings to functions. Not all functions have the same signature. For example, I'd like to have something like this:

rf := map[string]func(...interface{}) error{
    "FirstName":        validateExistence(a.FirstName, "FirstName is required."),
    "Postcode":         validateMatchPattern(a.Postcode, `^\d{5}$`, "Could not match pattern for postcode."),
    "Address":          validateLength(a.Address, 0, 35, "Address must have up to 35 chars."),
}

I'm getting this error:

cannot use validateExistence("FirstName is required.") (type func(string) error) as type func(...interface {}) error in map value

If I change the map declaration to map[string]func(f string, m string) error the error for the FirstName is solved, but I get other errors for the other two functions:

cannot use validateMatchPattern(a.Postcode, "^\\d{5}$", "Could not match pattern for postcode.") (type error) as type func(string) error in map value
cannot use validateLength(a.Address, 0, 35, "Address must have up to 35 chars.") (type error) as type func(string) error in map value

I understand the issue is in the map declaration, in the func(...interface{}) to be more precise. This part must have the same signatures as the function I'm using as key.

So, my question is: is there any other way to declare the map that can hold functions with different signatures?

  • 写回答

1条回答 默认 最新

  • dongyi6845 2018-10-10 11:13
    关注

    If I was designing this, I'd break this problem down like so:

    1. I want a map of validators, each of which takes a string and returns a human-readable error.
    2. I want to be able to pair a simple validator that returns a yes-or-no answer with an error message.
    3. I need a set of simple validators.

    Note that in all of these cases you need functions that return functions. The length validator, for example, can be:

    func validateLength(min, max int) func(string) bool {
            return func(s string) bool {
                    return len(s) >= min && len(s) <= max
            }
    }
    

    Then you can wrap this in a function that produces the error

    func makeValidator(f func(string) bool, msg string) func(string) error {
            return func(s string) error {
                    if !f(s) {
                            return errors.New(msg)
                    }
                    return nil
            }
    }
    

    Now you have a couple of layers that build the functions that go into the map, so you can create

    rt := map[string]func(string) error {
            "Address": makeValidator(
                    validateLength(0, 35),
                    "Address must have up to 35 chars."
            )
    }
    

    This doesn't pair it with the specific field (and indeed the suggestion from comments to just write this in code is probably a good one) but if you needed this to really be generic you could use reflection to look at the contents of a structure.

    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog