Ich denke, die Geschichte von Go's Null ist die n-te Abkochung, aber ich werde einen Artikel schreiben, um meiner Sucht zu gedenken.
Da der eigentliche Code etwas länger ist und sich im Framework befindet, war es schwierig, die Ursache zu identifizieren, aber ich werde nur das Wesentliche schreiben.
Ich wollte übrigens eine Wrapper-Funktion sein, weil ich HTTPRequest oft in den Testcode wirf.
func Request(method, url string, body *strings.Reader) error {
request, err := http.NewRequest(method, url, body)
if err != nil {
return err
}
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
client := new(http.Client)
resp, _ := client.Do(request)
defer resp.Body.Close()
byteArray, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(byteArray))
return nil
}
Ich gehe davon aus, dass Sie diese Methode auf diese Weise verwenden.
func main() {
values := url.Values{
"hoge": []string{"fuga"},
}
err := Request("POST", "https://google.com", strings.NewReader(values.Encode()))
if err != nil {
log.Fatal(err)
}
}
Für das dritte Argument von Request, ~~ Grob ~~, habe ich den Rückgabetyp von Strings angegeben. NewReader wie er ist, ohne an irgendetwas zu denken.
Jetzt, wenn es im POST nichts zum Senden von Parametern gibt
err := Request("POST", "https://google.com", nil)
if err != nil {
log.Fatal(err)
}
Ich gebe an, aber wenn ich das ausführe
Es stürzt mit einem Laufzeitfehler ab.
strings.(*Reader).Len(...)
/usr/local/Cellar/go/1.15.3/libexec/src/strings/reader.go:26
net/http.NewRequestWithContext(0x1314620, 0xc00001a0b0, 0x12baeec, 0x3, 0x12be7e1, 0x12, 0x13102c0, 0x0, 0x121018d, 0x0, ...)
/usr/local/Cellar/go/1.15.3/libexec/src/net/http/request.go:889 +0x2a4
net/http.NewRequest(...)
/usr/local/Cellar/go/1.15.3/libexec/src/net/http/request.go:813
main.Request(0x12baeec, 0x3, 0x12be7e1, 0x12, 0x0, 0x0, 0x0)
Übrigens ist es in Ordnung, wenn Sie nil direkt im dritten Argument von http.NewRequest angeben.
req, err := http.NewRequest("POST", "https://google.com", nil)
if err != nil {
log.Fatal(err)
}
Wie Sie sehen können, indem Sie durch IntelliJ IDEA gehen,
https://github.com/golang/go/blob/f2eea4c1dc37886939c010daff89c03d5a3825be/src/net/http/request.go#L887
if body != nil {
Go's nil ist eine typisierte Semantik, daher geht es in die Funktion mit dem Typ * strings.NewReader, obwohl der Body selbst im folgenden Code nil ist. Der Typ des Körpers selbst ist * strings.NewReader, und die Körperdeklaration ist io.Reader. Das Null-Urteil ist wahr (ungewollt?), Und es bedeutet, dass es im Wenn ist und ein Fehler auftritt.
Referenz: https://qiita.com/umisama/items/e215d49138e949d7f805
req, err := http.NewRequest("POST", "https://google.com", nil)
Nun das hier angegebene Null aus der Definition von NewRequest Es wird null von io.Reader. (Io.Reader wird auch in die Schnittstelle eingegeben)
func Request(method, url string, body *strings.Reader)
Argument von
func Request(method, url string, body io.Reader)
Es hätte sein sollen, obwohl es sich im Test um eine Einwegfunktion handelt, Es war sicher, das Funktionsargument dem Typ der darin verwendeten Funktion zuzuordnen, nicht dem Typ des Aufrufers.
Wenn im dritten Argument von http.NewRequest nil angegeben ist, geben Sie an, dass es sich um den Typ von io.Reader handelt.
Deklarieren Sie Funktionsargumente so nah wie möglich an dem darin aufgerufenen Typ.
Es wird oft gesagt, dass Null davon abhängig ist, aber ich dachte, dass ich es nicht bemerken würde, wenn ich nicht tatsächlich davon abhängig wäre.