Heim >Backend-Entwicklung >Golang >Welche Umgebungen sind in einem Verschluss enthalten?

Welche Umgebungen sind in einem Verschluss enthalten?

WBOY
WBOYnach vorne
2024-02-10 11:12:09994Durchsuche

Welche Umgebungen sind in einem Verschluss enthalten?

php Der in der geschlossenen Umgebung enthaltene Umweltbereich bezieht sich auf die in der geschlossenen Umgebung enthaltenen Elemente, Faktoren und Bedingungen. Eine geschlossene Umgebung bezieht sich auf einen relativ geschlossenen und eingeschränkten Raum oder Bereich, bei dem es sich um einen physischen Raum wie ein Labor oder eine Fabrikhalle oder um einen virtuellen Raum wie ein Computernetzwerk handeln kann. In einer geschlossenen Umgebung können verschiedene Faktoren wie Temperatur, Luftfeuchtigkeit, Gaszusammensetzung usw. kontrolliert und angepasst werden, um bestimmte Zwecke zu erreichen. Geschlossene Umgebungen sind in wissenschaftlichen Forschungsexperimenten, in der Produktion und Fertigung sowie in anderen Bereichen weit verbreitet und spielen eine wichtige Rolle bei der Gewährleistung der experimentellen Genauigkeit und Produktqualität.

Frageninhalt

Ich habe Online-Tutorials zum Thema Schließungen nachgeahmt und den folgenden Code geschrieben.

func foo1() func() {
    xvalue := 1
    x := &xvalue
    defer func() {
        xvalue = 2
    }()
    return func() {
        *x = *x + 1
        fmt.printf("foo1 val = %d\n", *x)
    }
}

func main() {

    f1 := foo1()
    f1()
    f1()
    f1()
}

Ich bin verwirrt, während der Ausführung f1 := foo1() 后,变量 xvalue 似乎应该被回收,因此使用 *x sollte es falsch sein, aber der obige Code hat keine Fehler und wird einwandfrei ausgeführt und liefert die Ausgabe

foo1 val = 3
foo1 val = 4
foo1 val = 5

Ich möchte also wissen, ob der Abschluss zusätzlich zum Zeiger selbst auch den Wert des Zeigers speichert oder ob der Garbage-Collection-Mechanismus der Go-Sprache dazu führt, dass der x-Wert nicht gelöscht wird?

Workaround

In Go erhält ein Abschluss einen Verweis auf (die Adresse) jeder Variablen, die er schließt. Zitat Sprachreferenz:

Funktionsliterale sind Abschlüsse: Sie können auf Variablen verweisen, die in umgebenden Funktionen definiert sind. Diese Variablen werden dann von umgebenden Funktionen und Funktionsliteralen gemeinsam genutzt und bleiben bestehen, solange auf sie zugegriffen werden kann.

Also, in deinem Beispiel:

  1. f1 := foo1()

    1. Sorgen Sie dafür, dass die Variable xValue vorhanden ist (der Compiler weist sie möglicherweise auf dem Heap zu). Es beginnt mit dem Nullwert 0 für seinen Typ.
    2. Machen Sie die Variable x 存在并为其分配 xValue existierend und weisen Sie ihr die Adresse von
    3. zu.
    4. Der defer-red 闭包运行并将值 2 分配给 xValuedefer-red-Abschluss wird ausgeführt und weist
    5. den Wert 2 zu.
    6. xGibt einen Abschluss zurück, der die Variable schließt
    7. .

    x,编译器保证即使在 foo 返回后该变量也存在。由于 x 包含 xValueDer letzte Punkt kann etwas knifflig sein: Da der zurückgegebene Abschluss auf die Variable verweist xValue, garantiert der Compiler, dass die Variable auch nach der Rückkehr von foo existiert. Da

    die Adresse von
  2. enthält (und daher ein Live-Verweis darauf ist), existiert diese Adresse noch und kann nicht durch Müll gesammelt werden. Mithilfe derselben Escape-Analysemethode garantiert der Compiler, dass
  3. die Rückkehr seiner deklarierten Funktion überlebt.

    xValue

  4. Sie führen den zurückgegebenen Abschluss aus, der durch den Zeiger darauf geändert wird
– hier passiert keine Magie. Die anderen beiden Aufrufe führen den gleichen Vorgang aus.

🎜 🎜Um es zusammenzufassen: Vielleicht stolpern Sie über die C++-Kenntnisse: Sobald die Kontrolle von der Funktion zurückgegeben wird, existiert jede innerhalb der Funktion deklarierte Variable nicht mehr, sodass jeder Verweis auf diese Variable, der außerhalb der Funktion existiert, ungültig wird. In Go ist dies nicht der Fall: Die Sprache ist in dieser Hinsicht ausdrücklich als sicher definiert: Der Compiler stellt sicher, dass jede Variable über eine ordnungsgemäße Zuweisung verfügt, sodass bei ihrer Erstellung ein Verweis darauf zurückgegeben (oder auf andere Weise übermittelt) wird Anrufe. Von dieser Funktion aus werden Aufrufe an die Außenwelt getätigt. 🎜

Das obige ist der detaillierte Inhalt vonWelche Umgebungen sind in einem Verschluss enthalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen