Golang ServeMux 仅被评估一次

问题描述 投票:0回答:2

我在 Go 程序中看到一些意外行为,希望有人可以向我解释一下。 我有以下基本程序:

    package main

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

func main() {
    runserver()
}

func runserver() {
    err := http.ListenAndServe(":5000", mux())
    if err != nil {
        log.Fatal(err)
    }
}

func mux() *http.ServeMux {
    mux := http.NewServeMux()

    mux.HandleFunc("/p1", func1)
    mux.HandleFunc("/p2", func2)
    mux.HandleFunc("/p3", midd("hello", func3))

    return mux
}

func func1(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 1")
    w.Write([]byte("hello from 1"))
}

func func2(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 2")
    w.Write([]byte("hello from 2"))
}

func func3(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 3") 
    w.Write([]byte("hello from 3"))
}

func midd(random string, hfunc http.HandlerFunc) http.HandlerFunc {
    fmt.Println(random)

    return hfunc
}

当我运行程序时,我立即看到终端中打印出 hello(来自 func midd)。 当我导航到 localhost:5000/p1 时,它会打印“叫 1”,如果我导航到 /p2,它会打印“叫 2”,但是当我导航到 /p3 时,我会在终端中看到“叫 3”,但不是 hello

任何人都可以向我解释为什么在程序启动时调用 midd() 而不是在我导航到“/p3”时调用

提前致谢!

go closures servemux
2个回答
2
投票

语句

mux.HandleFunc("/p3", midd("hello", func3))
执行
midd("hello", func3)
调用表达式 “then and there” 并将其结果传递给
mux.HandleFunc
函数调用。然后,为每个传入的
HandleFunc
请求调用传递给
/p3
的结果。

并且上述语句仅执行一次,因为mux()

runserver()
仅调用一次,并且runserver()
main()
仅调用一次,并且main()
被执行
仅一次.


0
投票
您可能对

高阶函数感到困惑。 mux.HandleFunc

 将函数作为第二个参数,但不会(立即)执行它,仅在调用注册的 URL 时使用。另外,当您调用 midd
 时,它会立即执行(打印其参数 
random
),但将其函数参数 
hfunc
 作为值返回,而不执行该函数。也许这会让事情变得更清晰(
Go Playground):

package main import "fmt" func main() { f := createFunction() fmt.Println("First") executeFunction(f) } func createFunction() func() { return func() { fmt.Println("Second") } } func executeFunction(f func()) { f() }
    
© www.soinside.com 2019 - 2024. All rights reserved.