Запрос перенаправления в Go, карта HandleFuncs

Я хочу сопоставить пути к файлам, которые живут в другом месте. Но мой код служит /path/c.txt когда я посещаю /a, вместо /path/a.txt, Что я делаю неправильно?

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fileRoutes := map[string]string {
        "/a": "/path/a.txt",
        "/b": "/path/b.txt",
        "/c": "/path/c.txt",
    }

    for req, path := range fileRoutes {
        http.HandleFunc(req, func(w http.ResponseWriter, r *http.Request) {
            fmt.Printf("actual request: %v\n", r.URL.Path)
            fmt.Printf("registered request: %v\n", req)

            r.URL.Path = path

            fmt.Println(req)
            fmt.Println(path)

            // serveFile(w, r)
        })
    }

    http.ListenAndServe(":8004", nil)
}

Этот пример кода производит:

actual request: /a
registered request: /c
/c
/path/c.txt

Спасибо!

2 ответа

Решение

Проблема в том, что все функции дескриптора обращаются одинаково req а также path который установлен в последнюю переменную цикла после цикла, которые /c а также /path/c.txt,

Чтобы исправить проблему, добавьте req,path := req,path до http.HandleFunc(...),

Это кажется странным. Что он делает, чтобы объявить новый req а также path в области цикла, которая является новой для каждой итерации, поэтому каждое замыкание связывается с различным значением.

Другое решение было бы тем, которое используется здесь (которое я благодаря ответу теперь понимаю): https://github.com/golang/blog/blob/master/rewrite.go:

path := fileRoutes[req] до http.HandleFunc

Другие вопросы по тегам