Eine Geschichte, nach der ich süchtig war, als ich in Go nil als Funktionsargument angab

Vorwort

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 habe eine Methode wie diese gemacht (Fehlerbeispiel)

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.

Geben Sie null an

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)
	}

Was ist der Grund für den Fehler?

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

Wenn im Funktionsargument nil angegeben ist, wird es zum Argumenttyp der Funktionsdeklaration.

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)

Was soll ich machen

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.

Fazit

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.

Recommended Posts

Eine Geschichte, nach der ich süchtig war, als ich in Go nil als Funktionsargument angab
Wovon ich beim Erstellen von Webanwendungen in einer Windows-Umgebung abhängig war
[Fabric] Ich war süchtig danach, Boolesche Werte als Argument zu verwenden. Notieren Sie sich also die Gegenmaßnahmen.
Eine Geschichte, von der ich bei np.where süchtig war
Eine Geschichte, der ich nach der SFTP-Kommunikation mit Python verfallen war
Als ich versuchte, PIL und matplotlib in einer virtuellen Umgebung zu installieren, war ich süchtig danach.
Die Platte, von der ich süchtig war, als ich MeCab in Heroku einsetzte
Ein Hinweis, von dem ich süchtig war, als ich unter Linux einen Piepton machte
Ein Hinweis, dem ich beim Erstellen einer Tabelle mit SQL Alchemy verfallen war
Erstellen Sie eine Funktion, um den Inhalt der Datenbank in Go abzurufen
Als ich versuchte, mithilfe von Anforderungen in Python zu kratzen, war ich süchtig nach SSLError, also einem Workaround-Memo
Eine Geschichte, die nicht funktioniert hat, als ich versucht habe, mich mit dem Python-Anforderungsmodul anzumelden
Eine Geschichte, die mich süchtig nach dem Versuch machte, LightFM unter Amazon Linux zu installieren
Eine Geschichte, die ich süchtig danach war, eine Video-URL mit Tweepy zu bekommen
Der Dateiname war in Python schlecht und ich war süchtig nach Import
[Python] Ich habe versucht, den Typnamen als Zeichenfolge aus der Typfunktion abzurufen
Ein Hinweis, dem ich beim Ausführen von Python mit Visual Studio Code verfallen war
Ich habe keine Angst, eine Programmierumgebung aufzubauen.
Als ich in IPython versuchte, den Wert zu sehen, war es ein Generator, also kam ich auf ihn, als ich frustriert war.
Ich war süchtig danach, 2020 mit Selen (+ Python) zu kratzen
Ein einfacher Unterschied bei der Übergabe eines Zeigers als Funktionsargument
Ich war süchtig danach, logging.getLogger mit Flask 1.1.x zu versuchen
Wovon ich süchtig war, als ich Python Tornado benutzte
Ich war nüchtern süchtig danach, awscli von einem in crontab registrierten Python 2.7-Skript aus aufzurufen
Eine Geschichte, die praktisch war, als ich versuchte, das Python-IP-Adressmodul zu verwenden
Beachten Sie, dass ich süchtig nach dem npm-Skript war, das in der Überprüfungsumgebung nicht übergeben wurde
Wovon ich süchtig war, als ich Klassenvererbung und gemeinsame Tabellenvererbung in SQLAlchemy kombinierte
Was ich getan habe, als ich wütend war, es mit der Option enable-shared einzufügen
Wenn eine lokale Variable mit demselben Namen wie die globale Variable in der Funktion definiert ist
Was den in Honchos Procfile geschriebenen Prozesstyp betrifft, war ich über eine Stunde lang süchtig danach, weil ich ihn nicht verwenden konnte - also werde ich ihn als Show schreiben.
[Kleine Geschichte] Eine sorgfältige Maßnahme, wenn Sie vor dem Import in Python eine Funktion ausführen müssen
Wörter, die mich als Programmieranfänger interessiert haben
Eine Geschichte, die verschwunden ist, als ich einen Pfad angegeben habe, der mit tilda (~) in Python Open beginnt
Wovon ich süchtig war, als der Processing-Benutzer zu Python wechselte
Ich habe es in der Sprache Go geschrieben, um das SOLID-Prinzip zu verstehen
Ich habe versucht, die Mail-Sendefunktion in Python zu implementieren
Die Geschichte, als ich von Caused by SSLError abhängig war ("Kann keine Verbindung zur HTTPS-URL herstellen, da das SSL-Modul nicht verfügbar ist.")
Eine Geschichte über das Schreiben von AWS Lambda und ein wenig Abhängigkeit von den Standardwerten von Python-Argumenten
Beachten Sie, dass ich süchtig danach war, mit Pythons mysql.connector über eine Webanwendung auf die Datenbank zuzugreifen
Als ich Django in mein Home-Verzeichnis legte, wurde ich mit einem Berechtigungsfehler in eine statische Datei eingebunden
[Linux] Ich möchte das Datum wissen, an dem sich der Benutzer angemeldet hat
Vorsichtsmaßnahmen bei Verwendung einer Liste oder eines Wörterbuchs als Standardargument
Wovon ich süchtig war, als ich ALE in Vim für Python einführte
Was ich mit json.dumps in Pythons base64-Codierung süchtig gemacht habe
Ich habe eine Funktion zum Laden des Git-Erweiterungsskripts in Python geschrieben
Verwendung von Lambda (beim Übergeben einer Funktion als Argument einer anderen Funktion)
Die Geschichte, dass der Wachmann eingesperrt war, als das Labor auf IoT umgestellt wurde
Ich war süchtig nach falschen Klassenvariablen und Instanzvariablen in Python
Ich habe den Befehl gegeben, einen farbenfrohen Kalender im Terminal anzuzeigen
Eine Geschichte, die von Azure Pipelines abhängig ist
Ich war süchtig nach Multiprocessing + Psycopg2
Ich möchte die Mühe der Eingabe beim Debuggen von Paizas Skill-Check-Beispiel in einer lokalen Umgebung wie Jupyter [Python] sparen.
[Python] Als ich versuchte, ein Dekomprimierungswerkzeug mit einer Zip-Datei zu erstellen, die ich gerade kannte, war ich süchtig nach sys.exit ()
Die Geschichte, wie ein Geschäft BOT (AI LINE BOT) nach Go To EAT in der Präfektur Chiba durchsucht (1)
Ich möchte das Pytest-Gerät als Bibliothek an einer anderen Stelle laden (Pytest ist möglicherweise nicht in der Umgebung vorhanden).