在 go 中使用全局变量时,必须注意类型匹配和赋值方式:声明为指针类型(如 `*rest.api`)后,需用 `=` 而非 `:=` 赋值,否则会意外创建同名局部变量,导致全局变量未被初始化。
Go 不支持真正的“动态作用域”,所有变量作用域严格由词法决定。在你的代码中,问题根源在于两个关键错误:
✅ 正确做法如下:
package main
import (
"github.com/ant0ine/go-json-rest/rest"
"log"
"net/http"
)
type Message st
ruct {
Body string
}
var api *rest.Api // ✅ 声明为指针类型 *rest.Api
func hostLookup(w rest.ResponseWriter, req *rest.Request) {
ip, err := net.LookupIP(req.PathParam("host"))
if err != nil {
rest.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteJson(&ip)
}
func foo() {
api = rest.NewApi() // ✅ 使用 = 赋值,修改全局变量
api.Use(rest.DefaultDevStack...)
router, err := rest.MakeRouter(
&rest.Route{"GET", "/lookup/#host", hostLookup},
)
if err != nil {
log.Fatal(err)
}
api.SetApp(router)
}
func bar() {
// ✅ 此时 api 已初始化,MakeHandler() 可安全调用
log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))
}
func main() {
foo()
bar()
}⚠️ 注意事项:
总结:Go 的简洁性依赖于明确的语义——:= 是声明,= 是赋值;类型必须精确匹配,尤其是指针与值的区别。修复这两点,即可让全局 api 正确承载路由逻辑并响应请求。