【问题标题】:Go map of functions功能图
【发布时间】:2011-10-09 18:53:30
【问题描述】:

我有一个定义了函数的 Go 程序。我还有一张地图,每个功能都应该有一个键。我该怎么做?

我已经试过了,但这不起作用。

func a(参数字符串){ } 米:=地图[字符串]函数{ 'a_func':一个, } 对于键,值:= 范围 m { 如果键 == 'a_func' { 值(参数) } }

【问题讨论】:

    标签: map go key-value func


    【解决方案1】:

    我使用了 ma​​p[string]func (a type, b *type) 我传递了一个字符串来搜索地图并传递一个指针来修改切片。

    希望有帮助!

    var Exceptions map[string]func(step string, item *structs.Item)
    
    func SetExceptions() {
        Exceptions = map[string]func(a string, i *structs.Item){
            "step1": step1,
        }
    }
    
    func RunExceptions(state string, item *structs.Item) {
        method, methBool := Exceptions[state]
        if methBool {
            method(state, item)
        }
    }
    
    func step1(step string, item *structs.Item) {
        item.Title = "Modified"
    }
    

    【讨论】:

      【解决方案2】:

      这是我在我的案例中使用它的方式:

      package main
      
      import (
          "fmt"
      )
      
      var routes map[string]func() string
      
      func main() {
          routes = map[string]func() string{
              "GET /":      homePage,
              "GET /about": aboutPage,
          }
      
          fmt.Println("GET /", pageContent("GET /"))
          fmt.Println("GET /about", pageContent("GET /about"))
          fmt.Println("GET /unknown", pageContent("GET /unknown"))
          // Output:
          // GET / Home page
          // GET /about About page
          // GET /unknown 404: Page Not Found
      }
      
      func pageContent(route string) string {
          page, ok := routes[route]
          if ok {
              return page()
          } else {
              return notFoundPage()
          }
      }
      
      func homePage() string {
          return "Home page"
      }
      
      func aboutPage() string {
          return "About page"
      }
      
      func notFoundPage() string {
          return "404: Page Not Found"
      }
      

      https://play.golang.org/p/8_g6Di1OKZS

      【讨论】:

        【解决方案3】:

        @Seth Hoenig 的回答对我帮助最大,但我只想补充一点,Go 也接受具有定义返回值的函数:

        package main
        
        func main() {
            m := map[string]func(string) string{
                "foo": func(s string) string { return s + "nurf" },
            }
        
            m["foo"]("baz") // "baznurf"
        }
        

        如果您认为它很难看,您可以随时使用类型(请参阅 @smagch 的回答)。

        【讨论】:

        【解决方案4】:

        如果函数是同一个接口,你可以定义一个类型。

        package main
        
        import "log"
        
        type fn func (string)
        
        func foo(msg string) {
          log.Printf("foo! Message is %s", msg)
        }
        
        func bar(msg string) {
          log.Printf("bar! Message is %s", msg)
        }
        
        func main() {
          m := map[string] fn {
            "f": foo,
            "b": bar,
          }
          log.Printf("map is %v", m)
          m["f"]("Hello")
          m["b"]("World")
        }
        

        【讨论】:

          【解决方案5】:
          m := map[string]func(string, string)
          

          如果你知道签名就可以工作(并且所有函数都具有相同的签名) 我认为这比使用界面更清洁/更安全{}

          【讨论】:

          • 所有函数的签名不同。
          • 其实我认为这回答了我上面的问题;我的函数具有相同的签名。但是......在这里我看到地图值是一个带参数的函数。有趣的是,我会尝试这样做,并且只传递要比较的参数。
          • 另外,假设函数返回一个字符串变量,它看起来像这样:m := map[string]func(string, string)string
          【解决方案6】:

          您是否正在尝试做这样的事情?我已经修改了示例以使用不同类型和数量的函数参数。

          package main
          
          import "fmt"
          
          func f(p string) {
              fmt.Println("function f parameter:", p)
          }
          
          func g(p string, q int) {
              fmt.Println("function g parameters:", p, q)
          }
          
          func main() {
              m := map[string]interface{}{
                  "f": f,
                  "g": g,
              }
              for k, v := range m {
                  switch k {
                  case "f":
                      v.(func(string))("astring")
                  case "g":
                      v.(func(string, int))("astring", 42)
                  }
              }
          }
          

          【讨论】:

          • 这几乎正是我所需要的,但假设 g 需要 2 个字符串参数。这可能吗?
          • 你能详细说明一下“v.(func(string))”吗?这似乎几乎需要反射包。这里的括号是否进行任何转换,还是全部处理基本接口?
          • 你可以不使用 f 和 g 作为地图值,而是在那里有字符串值,而是在 case "f": 下调用 f(mapValue) 吗?
          • 如果你的函数来自结构类型怎么办?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-14
          • 2013-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多