2015-06-30 86 views
2
package main 

import (
    "net/http" 
) 

func main() { 
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ 
     w.Write([]byte("hello world")) 
    }) 
    http.ListenAndServe(":8000", nil) 
} 

如果刪除了*http.Request爲什麼必須將http.Request參數作爲指針?

github.com/creating_web_app_go/main.go:8:不能使用FUNC字面(類型FUNC(http.ResponseWriter,http.Request))作爲類型func(http.ResponseWriter,* http.Request)參數http.HandleFunc

我對Go和指針都很陌生。

所以問題是, 爲什麼必須http.Request是一個指針,而不是一個func literal?任何人都可以用最簡單的方式解釋這個,也許可以參考源代碼?

+0

爲什麼-1?這真的是一個很好的問題嗎? –

+0

其實這是一個非常好的問題imo – Yar

回答

8

因爲它是一個很大的結構。複製它會很昂貴。所以它是一個指向結構的指針,當結構很大時這在Go中很常見。它也有一些狀態,所以如果複製它可能會令人困惑。做一個func文字是沒有意義的;我不明白爲什麼這是一個選項。

+0

是的,func文字只是它拋出的錯誤,當你不把它設置爲指針。 –

2

因爲這就是函數的工作原理。他們有爭論,當你調用它們時,你必須提供必要的參數。類型也必須相同。

我認爲你真的在問,它爲什麼這樣設計?

因爲您在向根"/"發出請求時要調用http.HandleFunc的代理。在大多數情況下,當一個RESTful API處理請求時,它需要知道請求中的信息,比如頭部,查詢參數和/或帖子主體等。如果你不想使用這些信息,不必要,將一個引用傳遞給一個函數的開銷並不大。但是對於幾乎所有的實際用例,數據都是需要的,因此它被包含在內,因此它在您提供的代表中成爲參數。從實施的持續性來看,他們需要知道您提供的方法簽名是什麼,以便他們可以調用它。

爲了澄清,您正在查看的是您作爲http.HandleFunc的第二個參數func所需的簽名。第一個參數是路徑。當對所提供的路徑進行http請求時,它會調用該方法。該代碼將調用該參數稱爲handler,它需要一個一致的定義,以便它可以執行handler(resp, req),而不必爲了調用代碼而執行反射或切換或其他控制流。

+1

很多好吃的東西,我不得不深入,即委託,反射,控制流大聲笑,但我會認爲這是最正確的答案。感謝您的努力!我會把這一切都看出來:) –

+1

@MatthewHarwood記住我的描述是相當抽象的。這樣做的代碼本身就在這裏; http://golang.org/src/net/http/server.go如果你想看看'HandleFunc'實際上做了什麼'func(w http.ResponseWriter,r * http.Request)'參數。此外,請注意,您可以在其他地方通常使用該sig定義函數,並按名稱傳遞它。 – evanmcdonnal

相關問題