【问题标题】:function in map is <nil>地图中的功能是 <nil>
【发布时间】:2015-03-08 11:49:16
【问题描述】:

我正在尝试在 Go 中构建一个简单的路由器,我在一个结构上有一个 get 方法,该方法应该将回调传递给 Get 路由映射,并以 url 作为键,似乎 fmt.Println(urlCallback) 返回一个 nil值并导致运行时恐慌,如果我试图调用它,来自 javascript 背景是 nil 那就太好了。

这是我的“路由器”包。

package Router

import (
    "fmt"
    "net/http"
    "net/url"
    "log"
)

type Res http.ResponseWriter
type Req *http.Request

type RouteMap map[*url.URL]func(Res, Req) 
type MethodMap map[string]RouteMap

type Router struct {
    Methods MethodMap
}

func (router *Router) Get(urlString string, callback func(Res, Req)) {
    parsedUrl, err := url.Parse(urlString)

    if(err != nil) {
        panic(err)
    }

    fmt.Println(parsedUrl)

    router.Methods["GET"][parsedUrl] = callback
}

func (router *Router) initMaps() {
    router.Methods = MethodMap{}
    router.Methods["GET"] = RouteMap{}
}

func (router Router) determineHandler(res http.ResponseWriter, req *http.Request) {
    fmt.Println(req.URL)
    fmt.Println(req.Method)

    methodMap := router.Methods[req.Method]
    urlCallback := methodMap[req.URL]

    fmt.Println(methodMap)
    fmt.Println(urlCallback)
}

func (router Router) Serve(host string, port string) {
    fullHost := host + ":" + port

    fmt.Println("Router is now serving to:" + fullHost)
    http.HandleFunc("/", router.determineHandler)

    err := http.ListenAndServe(fullHost, nil)

    if err == nil {
        fmt.Println("Router is now serving to:" + fullHost)
    } else {
        fmt.Println("An error occurred")
        log.Fatal(err)
    }
}


func NewRouter() Router {
    newRouter := Router{}
    newRouter.initMaps()

    return newRouter
}

还有我的主力。

package main

import (
    "./router"
    "fmt"
)

func main() {
    router := Router.NewRouter()

    router.Get("/test", func(Router.Res, Router.Req) {
        fmt.Println("In test woohooo!")
    })

    router.Serve("localhost", "8888")
}

【问题讨论】:

    标签: go


    【解决方案1】:

    您正在使用 *URL.url 对象作为映射键。由于两个不同的对象不会相同,因此您无法再次访问该路径的密钥。很恐慌,因为

    urlCallback := methodMap[req.URL]
    

    不是现有键,因此您访问的是 nil 值。在这种情况下,您可能想要做的是使用 URL.url 对象的 Path 属性。

    所以你有:

    type RouteMap map[string]func(Res, Req)
    

    Get():

    router.Methods["GET"][parsedUrl.Path] = callback
    

    对于determineRouter(),您可以这样做:

    urlCallback, exists := methodMap[req.URL.Path]
    if exists != false {
        urlCallback(res, req)
    }
    

    这会在尝试调用密钥之前添加一个检查以查看密钥是否存在。

    【讨论】:

    • 这很有意义,你的回答很有魅力。干杯!
    猜你喜欢
    • 2021-08-30
    • 1970-01-01
    • 2021-11-10
    • 2018-09-27
    • 2015-06-08
    • 1970-01-01
    • 2011-06-14
    • 2013-12-31
    • 2018-09-23
    相关资源
    最近更新 更多