dsnrixf6765 2016-11-11 14:47
浏览 57
已采纳

在Go中运行时访问符号

In writing a Web server in Go, I'd like to be able to dereference symbols at runtime, to allow me to figure out which functions to call from a configuration file, something like the call to the fictional "eval" function in the example below. That would allow me to select handlers from a library of handlers, and to deploy a new server with just a config file. Is there any way to accomplish this in Go?

config.json

{ "url": "/api/apple", "handler": "Apple", "method": "get" }
{ "url": "/api/banana", "handler": "Banana", "method": "get" }

play.go

package main

import (
    "github.com/gorilla/mux"
    "net/http"
    "encoding/json"
    "log"
)

type ConfigEntry struct {
    URL string `json:"url"`
    Method string `json:"method"`
    Handler string `json:"handler"`
}

func main() {
    ifp, err := os.Open("config.json")

    if err != nil {
        log.Fatal(err)
    }

    dec := json.NewDecoder(ifp)
    r := mux.NewRouter()

    for {
        var config ConfigEntry

        if err = dec.Decode(&m); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }

        r.HandleFunc(config.URL, eval(config.Handler + "Handler")).Methods(config.Method)
    }

    http.Handle("/", r)
    http.ListenAndServe(8080, nil)
}

func AppleHandler(w http.ResponseWriter, r *http.Request) (status int, err error) {
    w.Write("Apples!
")
    return http.StatusOK, nil
}

func BananaHandler(w http.ResponseWriter, r *http.Request) (status int, err error) {
    w.Write("Bananas!
")
    return http.StatusOK, nil
}
  • 写回答

2条回答 默认 最新

  • dslfq06464 2016-11-11 15:08
    关注

    There's nothing like eval in Go, which is a good thing since things like that are very dangerous.

    What you can do is have a map mapping the handler strings in your config file to the handler functions in your code:

    var handlers = map[string]func(http.ResponseWriter, *http.Request) (int, error){
            "Apple": AppleHandler,
            "Banana": BananaHandler,
    }
    

    Then you can register those handlers by simply doing:

    handler, ok := handlers[config.Handler]
    if !ok {
            log.Fatal(fmt.Errorf("Handler not found"))
    }
    r.HandleFunc(config.URL, handler).Methods(config.Method)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图