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 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line