如何在golang中构建自己的简单路由器?

one*_*ler 3 router go httpserver

我在golang中构建自己的路由器以理解逻辑,但是我得到404错误,通常没有找到,我能够运行到服务器但是我用hello名称写了函数,它没有运行.这可能是什么原因?

package main
import (
    "fmt"
    "log"
    "net/http"
    "strings"
    "time"
)

var Session *http.Server
var r Router

func Run(port string) {
    Session = &http.Server{
        Addr:           port,
        Handler:        &r,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    log.Fatal(Session.ListenAndServe())
}

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

type Router struct {
    mux map[string]Handle
}

func newRouter() *Router {
    return &Router{
        mux: make(map[string]Handle),
    }
}

func (r *Router) Add(path string, handle Handle) {
    r.mux[path] = handle
}

func GetHeader(url string) string {
    sl := strings.Split(url, "/")
    return fmt.Sprintf("/%s", sl[1])
}

func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    head := GetHeader(r.URL.Path)
    h, ok := rt.mux[head]
    if ok {
        h(w, r)
        return
    }
    http.NotFound(w, r)
}

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s", "hello world")
}

func main() {
    r := newRouter()
    r.Add("/hello", hello)
    Run(":8080")
}
Run Code Online (Sandbox Code Playgroud)

tho*_*eni 5

通过使用:=表示法,您的主要功能是声明并初始化一个名为r的新局部变量,其范围与您在列表顶部的全局变量不同.

这意味着r您要添加处理程序的变量不是您尝试分配给Http.Server结构的全局变量,因此您ServeHTTP将无法在其自己的接收器中找到任何映射r.

一个解决方案是声明r Router一个指向a的指针Router,如下所示:

var r *Router
Run Code Online (Sandbox Code Playgroud)

在你的处理程序中,你可以直接传递指针而不需要任何解除引用:

Session = &http.Server{
        Addr:           port,
        Handler:        r,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
Run Code Online (Sandbox Code Playgroud)

当然,请记住通过指定指针值而不是声明新的本地值来初始化变量:

func main() {
    r = newRouter()
    r.Add("/hello", hello)
    Run(":8080")
}
Run Code Online (Sandbox Code Playgroud)