当与函数切片一起使用时,Golang httpRouter返回最后一个响应

I am trying to implement expressjs like features to httprouter package . I create a struct type mounter

type Mounter struct {
    BasePath string
    Routes   []*Route
}

and a Route struct which represents subRoutes

type Route struct {
    Path   string
    Method string
    Func   Handle
}

type Handle func(http.ResponseWriter, *http.Request, Params)

type Params interface{}

i have a NewRoutes Function which is the main thing i wanted to port from expressjs new routes does the same thing as express.Router

func NewRoutes(base string) (mounter *Mounter) {
    mounter = &Mounter{
        BasePath: base,
    }
    return
}

and i have get post put delete methods under *Mounter

//GET request handler
func (mounter *Mounter) GET(path string, Func Handle) {
    mounter.Routes = append(mounter.Routes, &Route{path, "get", Func})
}

//POST request handler
func (mounter *Mounter) POST(path string, Func Handle) {
    mounter.Routes = append(mounter.Routes, &Route{path, "post", Func})
}

//PUT request handler
func (mounter *Mounter) PUT(path string, Func Handle) {
    mounter.Routes = append(mounter.Routes, &Route{path, "put", Func})
}

//DELETE request handler
func (mounter *Mounter) DELETE(path string, Func Handle) {
    mounter.Routes = append(mounter.Routes, &Route{path, "delete", Func})
}

and finally i have a Mount method which mounts the router to the actual router

func (mounter *Mounter) Mount(router *rtr.Router) {
    mounter.BasePath = strings.TrimSuffix(mounter.BasePath, "/")
    for _, route := range mounter.Routes {
        path := route.Path
        if !strings.HasSuffix(path, "/") {
            path += "/"
        }
        path = mounter.BasePath + path
        switch strings.ToLower(route.Method) {
        case "get":
            router.GET(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
                route.Func(res, req, params)
            })
        case "post":
            router.POST(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
                route.Func(res, req, params)
            })
        case "delete":
            router.DELETE(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
                route.Func(res, req, params)
            })
        case "put":
            router.PUT(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
                route.Func(res, req, params)
            })
        }
    }
}

everything works pretty nice and the methods are working fine too if i try to send a post request to a get endpoint it gives a nice 404 but the only issue is it always responds with the handler of last added member regardless of subpath so

package api
var ApiRouter = express.NewRoutes("/api/")

func init() {
    ApiRouter.GET("/", func(res http.ResponseWriter, req *http.Request, _ express.Params) {
        fmt.Fprintln(res, "testget/")
    })
    ApiRouter.GET("/pt", func(res http.ResponseWriter, req *http.Request, _ express.Params) {
        fmt.Fprintln(res, "pt")
    })
    ApiRouter.POST("/test", func(res http.ResponseWriter, req *http.Request, _ express.Params) {
        fmt.Fprintln(res, "test/post")
    })
}

package main
func main() {
    router := express.New()
    api.ApiRouter.Mount(router)
    for _, route := range api.ApiRouter.Routes {
        fmt.Println(*route)
    }
    router.ServeFiles("/public/*filepath", http.Dir("./public/"))
    http.ListenAndServe(":1024", router)
}

Will always respond test/post and the output of the range i am doing above for test purposes is So do you have any idea why it uses always the same function to respond but recognizes paths perfectly?

The problem lies in Mount method, which is known as Iteration Variables and Closures. Declare a new variable for capturing route e.g.

thisRoute := route //capture iteration variable
switch strings.ToLower(route.Method) {
case "get":
    router.GET(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
        thisRoute.Func(res, req, params)
    })
case "post":
    router.POST(path, func(res http.ResponseWriter, req *http.Request, params rtr.Params) {
        thisRoute.Func(res, req, params)
    })
//...
}