英文:
Struct value been stored in every request Golang using net/http
问题
我是新手学习 Golang,我正在测试 net/http 包来运行一些路径,但是我遇到了一些我不理解的问题。
以下是我的代码:
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
所以,当我访问 http://localhost:8080/
时,我得到了空的内容 index content {{false } map[]}
,
而当我访问 http://localhost:8080/test
时,我得到了正确的内容,test content {{false } map[data1:data 1 content data2:data 2 content]}
,
但是当我回到首页 http://localhost:8080/
时,那里已经有内容了,index content {{false } map[data1:data 1 content data2:data 2 content]}
,
所以问题是,为什么当我回到首页时,我没有得到空的结构体内容?我以为结构体会在每个请求时都处于初始状态?HTTP 应该是无状态的,对吗?
英文:
I am new to Golang, I am testing the net/http to run some path but I got some problem that I don't understand.
Here is my codes.
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404");
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
So, if I go to index http://localhost:8080/
, I got empty content index content {{false } map[]}
,
And I goto http://localhost:8080/test
I got the content correctly , test content {{false } map[data1:data 1 content data2:data 2 content]}
,
But when I go back to index http://localhost:8080/
there already content there index content {{false } map[data1:data 1 content data2:data 2 content]}
,
So question here, why am I not getting the empty struct content when I back to the index? I thought the struct will be in initial state with every single request? The http should be stateless, right?
答案1
得分: 1
你可能正在经历的是这段代码或类似的代码的结果(你的代码无法编译):
package main
import (
"fmt"
"net/http"
)
var Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
解决方案
你创建了一个全局变量 Content
,它在对 web 服务器的多次调用之间保持状态。你可能想要的是这样的:
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
var c Content
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", c)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
var c Content
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
c.Data = data
fmt.Println("test content ", c)
}
所做的更改
- 将
Content
声明为类型,就像你在示例中已经做的那样(这样它不再是全局变量,而是定义了一个我们可以重用的类型) - 在需要的每个调用中声明
Content
(不要全局声明,因为我们不希望它在服务器调用之间保持内容)
要点
在使用类型之前,你必须先声明一个变量。这就是为什么你的示例无法构建的原因。如果你尝试这样做,Go 将会抱怨 Content
不是一个表达式。
英文:
What you are probably experiencing is the result of this code or something similar (your code does not compile):
package main
import (
"fmt"
"net/http"
)
var Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
Solution
With this you are creating a global variable Content
that keeps its state across calls to the webserver. What you probably intended is this:
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
var c Content
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", c)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
var c Content
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
c.Data = data
fmt.Println("test content ", c)
}
Changes made
- make
Content
a type as you already did in your sample (that way it is not a global variable any more but defining a type we can reuse) - declare
Content
in each call where it is needed (not globally as we do not want it to keep its content across server calls)
Essence
You cannot use a type without declaring a variable from it first. That is why your sample did not build. If you try go will complain that Content
is not an expression.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论