2015-01-10 2 views
0

GO에서 간단한 라우터를 만들려고합니다. 콜백을 전달해야하는 구조체의 get 메소드가 있습니다. URL로 경로 맵을 키로 가져 오는 것이 좋습니다. fmt.Println(urlCallback)는 nil 값을 반환하고 javascript 백그라운드에서 오는 호출을 시도하면 런타임 패닉이 발생합니다. 포인터와 같은 점을 잡아 먹을 뿐이며 누군가가 말할 수 있다면 뭔가 관련이 있다고 느낍니다. 왜 통과 된 기능이 좋을지 모르는 이유.golang - map의 기능은 <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") 
} 

답변

5

지도 키에는 *URL.url 개체가 사용됩니다. 두 개의 다른 오브젝트가 같지 않으므로 해당 경로의 키에 다시 액세스 할 수 없습니다.

urlCallback := methodMap[req.URL] 

기존 키가 아닌 때문에 당황 것, 그래서 당신은 전무 값에 접근하고 있습니다. 이 경우에 수행하려는 작업은 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) 
} 

이이 있는지 확인하기 위해 검사를 추가 키가 호출되기 전에 존재합니다.

+0

완벽한 감각과 당신의 대답은 매력적이었습니다. 건배! – Melbourne2991