Je pense que l'histoire de go's nil est la nième décoction, mais j'écrirai un article pour commémorer ma dépendance.
Comme le code réel est un peu plus long et se trouve dans le cadre, il était difficile d'identifier la cause, mais je n'écrirai que l'essentiel.
Au fait, j'avais l'intention d'être une fonction wrapper car je lance HTTPRequest plusieurs fois dans le code de test.
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
}
Je suppose que vous utilisez cette méthode de cette façon.
func main() {
values := url.Values{
"hoge": []string{"fuga"},
}
err := Request("POST", "https://google.com", strings.NewReader(values.Encode()))
if err != nil {
log.Fatal(err)
}
}
Pour le troisième argument de Request, ~~ En gros ~~ j'ai spécifié le type de retour des chaînes.NewReader tel quel sans penser à rien.
Maintenant, quand il n'y a rien à envoyer de paramètres dans POST
err := Request("POST", "https://google.com", nil)
if err != nil {
log.Fatal(err)
}
Je précise, mais quand j'exécute ça
Il plante avec une erreur d'exécution.
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)
Au fait, ce n'est pas grave si vous spécifiez nil directement dans le troisième argument de http.NewRequest.
req, err := http.NewRequest("POST", "https://google.com", nil)
if err != nil {
log.Fatal(err)
}
Comme vous pouvez le voir en parcourant IntelliJ IDEA,
https://github.com/golang/go/blob/f2eea4c1dc37886939c010daff89c03d5a3825be/src/net/http/request.go#L887
if body != nil {
Go's nil est une sémantique typée, donc il entre dans la fonction avec le type de * strings.NewReader, même si le corps lui-même est nul dans le code ci-dessous. Le type du corps lui-même est * strings.NewReader et la déclaration du corps est io.Reader. Le jugement nul est vrai (involontairement?), Et cela signifie qu'il est dans le si et une erreur se produit.
référence: https://qiita.com/umisama/items/e215d49138e949d7f805
req, err := http.NewRequest("POST", "https://google.com", nil)
Maintenant le nil spécifié ici, à partir de la définition de NewRequest Il devient nul de io.Reader. (Io.Reader est également saisi dans l'interface)
func Request(method, url string, body *strings.Reader)
Argument de
func Request(method, url string, body io.Reader)
Cela aurait dû l'être, donc même s'il s'agit d'une fonction jetable dans le test, Il était sûr de faire correspondre l'argument de la fonction au type de la fonction utilisée à l'intérieur, pas au type de l'appelant.
Lorsque nil est spécifié dans le troisième argument de http.NewRequest, spécifiez-le comme étant le type de io.Reader.
Déclarez les arguments de fonction aussi proches que possible du type appelé à l'intérieur.
On dit souvent que nul n'y est accro, mais je pensais que je ne le remarquerais que si j'en étais réellement accro.
Recommended Posts