Wie verwende ich „defer' in Go mit geänderten Variablen richtig?
Klärung der Verwendung von „Defer“
In Go können wir mit der „defer“-Anweisung die Ausführung einer Funktion planen, kurz bevor die umgebende Funktion zurückkehrt. Dies kann jedoch zu Verwirrung führen, wenn es um Variablen geht, die innerhalb der einschließenden Funktion geändert werden.
Ursprüngliche Ausgabe
Betrachten Sie die folgende Funktion:
func printNumbers() { var x int defer fmt.Println(x) for i := 0; i < 5; i++ { x++ } }
Gemäß der Go-Spezifikation: Wenn eine „Defer“-Anweisung ausgeführt wird, werden der Funktionswert und die Parameter ausgewertet und für die spätere Ausführung gespeichert. Das bedeutet, dass, wenn die Funktion schließlich aufgerufen wird, der Wert von x immer noch 0 sein wird, da er zum Zeitpunkt der Verzögerung ausgewertet wurde.
Lösung mit anonymer Funktion
Um dieses Problem zu beheben, haben wir kann eine anonyme Funktion innerhalb der „defer“-Anweisung verwenden:
defer func() { fmt.Println(x) }()
Hier ist x kein Parameter der anonymen Funktion, daher wird es nicht ausgewertet, wenn die „defer“-Anweisung wird ausgeführt. Stattdessen wird der Wert von x zum Zeitpunkt des Aufrufs der anonymen Funktion erfasst, um sicherzustellen, dass der aktuellste Wert gedruckt wird.
Alternative Lösungen
-
Verwendung eines Zeigers:
var x int defer func() { fmt.Println(&x) }()
Nach dem Login kopierenDieser Ansatz verwendet einen Zeiger auf x als Parameter der verzögerten Funktion. Wenn die „defer“-Anweisung ausgeführt wird, wird nur der Zeiger ausgewertet, nicht der Wert von x. Wenn die verzögerte Funktion aufgerufen wird, greift sie über den Zeiger auf den aktuellen Wert von x zu.
-
Verwenden eines benutzerdefinierten Typs:
type MyInt int func (m *MyInt) String() string { return strconv.Itoa(int(*m)) } var x MyInt defer fmt.Println(&x)
Nach dem Login kopierenDiese Lösung ähnelt dem Zeigeransatz, verwendet jedoch einen benutzerdefinierten Typ (MyInt), der die String()-Methode implementiert. Durch die Implementierung von String() können wir steuern, wie der Wert von ein Deskriptortyp in Go, was bedeutet, dass sein Wert eine Referenz auf ein zugrunde liegendes Array ist. Wenn wir einen Slice verschieben, wird nur die Referenz ausgewertet, nicht die tatsächlichen Array-Elemente. Infolgedessen werden alle Änderungen, die nach der Verschiebung an den Slice-Elementen vorgenommen werden, in der gedruckten Ausgabe widergespiegelt.
-
Umschließen in einer Struktur:
var x []int defer fmt.Println(x)
Nach dem Login kopierenDieser Ansatz ähnelt der Verwendung eines Zeigers, aber wir packen den Wert in eine Struktur ein, um zu vermeiden, dass der Zeiger im Deferred dereferenziert werden muss Funktion.
Das obige ist der detaillierte Inhalt vonWie verwende ich „defer' in Go mit geänderten Variablen richtig?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

OpenSSL bietet als Open -Source -Bibliothek, die in der sicheren Kommunikation weit verbreitet sind, Verschlüsselungsalgorithmen, Tasten und Zertifikatverwaltungsfunktionen. In seiner historischen Version sind jedoch einige Sicherheitslücken bekannt, von denen einige äußerst schädlich sind. Dieser Artikel konzentriert sich auf gemeinsame Schwachstellen und Antwortmaßnahmen für OpenSSL in Debian -Systemen. DebianopensL Bekannte Schwachstellen: OpenSSL hat mehrere schwerwiegende Schwachstellen erlebt, wie z. Ein Angreifer kann diese Sicherheitsanfälligkeit für nicht autorisierte Lesen sensibler Informationen auf dem Server verwenden, einschließlich Verschlüsselungsschlüssel usw.

Wie kann man im Beegoorm -Framework die mit dem Modell zugeordnete Datenbank angeben? In vielen BeEGO -Projekten müssen mehrere Datenbanken gleichzeitig betrieben werden. Bei Verwendung von BeEGO ...

Backend Learning Path: Die Erkundungsreise von Front-End zu Back-End als Back-End-Anfänger, der sich von der Front-End-Entwicklung verwandelt, Sie haben bereits die Grundlage von Nodejs, ...

Das Problem der Verwendung von RETISTREAM zur Implementierung von Nachrichtenwarteschlangen in der GO -Sprache besteht darin, die Go -Sprache und Redis zu verwenden ...

Was soll ich tun, wenn die benutzerdefinierten Strukturbezeichnungen in Goland nicht angezeigt werden? Bei der Verwendung von Goland für GO -Sprachentwicklung begegnen viele Entwickler benutzerdefinierte Struktur -Tags ...

In der Bibliothek, die für den Betrieb der Schwimmpunktnummer in der GO-Sprache verwendet wird, wird die Genauigkeit sichergestellt, wie die Genauigkeit ...

Das Problem der Warteschlange Threading In Go Crawler Colly untersucht das Problem der Verwendung der Colly Crawler Library in Go -Sprache. Entwickler stoßen häufig auf Probleme mit Threads und Anfordern von Warteschlangen. � ...

In diesem Artikel wird vorgestellt, wie MongoDB im Debian -System konfiguriert wird, um eine automatische Expansion zu erzielen. Die Hauptschritte umfassen das Einrichten der MongoDB -Replikat -Set und die Überwachung des Speicherplatzes. 1. MongoDB Installation Erstens stellen Sie sicher, dass MongoDB im Debian -System installiert ist. Installieren Sie den folgenden Befehl: sudoaptupdatesudoaptinstall-emongoDB-org 2. Konfigurieren von MongoDB Replika-Set MongoDB Replikate sorgt für eine hohe Verfügbarkeit und Datenreduktion, was die Grundlage für die Erreichung der automatischen Kapazitätserweiterung darstellt. Start MongoDB Service: SudosystemctlstartMongodsudosysys
