我正在尝试计算每个新的动态URL
var count int
// *Error* non-declaration statement outside function body
func increment() error {
count = count + 1
return nil
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
m := make(map[string]int)
if r.Method != "POST" {
http.Error(w, "Method is not supported.", http.StatusNotFound)
return
}
increment()
b, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
urlPath := r.RequestURI
value, ok := m[urlPath]
if ok {
m[urlPath] = count + 1
fmt.Println("value: ", value)
} else {
m[urlPath] = count
fmt.Println(m)
fmt.Println("key not found")
}
fmt.Println(m)
fmt.Fprintf(w, "Hello!", count)
fmt.Printf("%s", b)
}
func main() {
http.HandleFunc("/report/", helloHandler) // Update this line of code
fmt.Printf("Starting server at port 8080n")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
结果应该是以所有URL作为关键字和次数作为值的映射,例如:{"abc":2"foo":1."ho":5}但当我每次运行代码时,密钥再次更新了一个agin
存在多个问题:
-
每次执行处理程序函数时都会创建一个新映射。
-
由于HTTP处理程序在并行运行的单独goroutine上执行,因此在全局
counter
变量上存在数据竞赛。
我真的不确定我是否正确解析了你想要的东西,但据说你应该:
- 有一张全球地图
- 让每个对该映射的访问都受到互斥锁的保护
- 递增计数器,它是映射中的值
类似这样的东西:
var (
hitsMu sync.Mutex
hits = make(map[string]*int)
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
// ...
hitsMu.Lock()
defer hitsMu.Unlock()
counterPtr := hits[urlPath]
if counterPtr == nil {
counterPtr = new(int)
hits[urlPath] = counterPtr
}
*counterPtr += 1
// ...
}