我在 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”时调用
提前致谢!
语句
mux.HandleFunc("/p3", midd("hello", func3))
执行 midd("hello", func3)
调用表达式 “then and there” 并将其结果传递给 mux.HandleFunc
函数调用。然后,为每个传入的 HandleFunc
请求调用传递给 /p3
的结果。
并且上述语句仅执行一次,因为mux()
被
runserver()
仅调用一次,并且runserver()
被
main()
仅调用一次,并且main()
被执行仅一次.
高阶函数感到困惑。
mux.HandleFunc
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()
}