849 Stimmen

Was ist lexikalischer Geltungsbereich?

Was ist eine kurze Einführung in das lexikalische Scoping?

109 Stimmen

In Podcast 58 ermutigt Joel zu Fragen wie diesen, da er möchte, dass SO DER Ort für Antworten wird, auch wenn sie bereits an anderer Stelle beantwortet wurden. Dies ist eine berechtigte Frage, auch wenn man sie etwas höflicher formulieren könnte.

0 Stimmen

Und dann speziell de.wikipedia.org/wiki/Scope_(Programmierung) die ein schönes (Pascal/Delphi) Beispiel für verschachtelte Bereiche in verschachtelten Prozeduren enthält.

18 Stimmen

Es ist möglich, dass der Fragesteller nicht fließend Englisch spricht (oder sprach), als er diese Frage schrieb.

800voto

Khaled Alshaya Punkte 90854

Ich verstehe sie durch Beispiele :)

Erstens, lexikalische Reichweite (auch genannt statischer Anwendungsbereich ), in C-ähnlicher Syntax:

void fun()
{
    int x = 5;

    void fun2()
    {
        printf("%d", x);
    }
}

Jede innere Ebene kann auf ihre äußeren Ebenen zugreifen.

Es gibt noch einen anderen Weg, der heißt dynamischer Umfang die bei der ersten Implementierung von Lispeln , wiederum in einer C-ähnlichen Syntax:

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

Hier fun kann entweder auf x en dummy1 o dummy2 oder jede x in jeder Funktion, die fun con x darin erklärt.

dummy1();

wird 5 gedruckt,

dummy2();

wird 10 gedruckt.

Die erste wird statisch genannt, weil sie zur Kompilierzeit abgeleitet werden kann, und die zweite wird dynamisch genannt, weil der äußere Bereich dynamisch ist und vom Kettenaufruf der Funktionen abhängt.

Ich finde das statische Scoping einfacher für das Auge. Die meisten Sprachen sind irgendwann in diese Richtung gegangen, sogar Lisp (kann beides, oder?). Dynamisches Scoping ist wie die Übergabe von Referenzen auf alle Variablen an die aufgerufene Funktion.

Als Beispiel dafür, warum der Compiler den äußeren dynamischen Bereich einer Funktion nicht ableiten kann, betrachten Sie unser letztes Beispiel. Wenn wir etwas wie dieses schreiben:

if(/* some condition */)
    dummy1();
else
    dummy2();

Die Aufrufkette hängt von einer Laufzeitbedingung ab. Wenn sie wahr ist, dann sieht die Aufrufkette wie folgt aus:

dummy1 --> fun()

Wenn die Bedingung falsch ist:

dummy2 --> fun()

Der äußere Rahmen von fun ist in beiden Fällen der Anrufer sowie der Anrufer des Anrufers usw. .

Ich möchte nur erwähnen, dass die Sprache C weder verschachtelte Funktionen noch dynamisches Scoping zulässt.

20 Stimmen

Ich möchte auch auf ein sehr einfach zu verstehendes Tutorial hinweisen, das ich gerade gefunden habe. Das Beispiel von Arak ist nett, aber vielleicht zu kurz für jemanden, der mehr Beispiele braucht (eigentlich, wenn man es mit anderen Sprachen vergleicht ). Schauen Sie es sich an. Es ist wichtig zu verstehen este da dieses Schlüsselwort zum Verständnis der lexikalischen Reichweite beiträgt. howtonode.org/was-ist-das

0 Stimmen

Es ist gut zu wissen, dass gcc eine Erweiterung hat, die verschachtelte Funktionen erlaubt.

24 Stimmen

Dies ist eine gute Antwort. Aber die Frage ist getaggt mit JavaScript . Daher sollte dies meiner Meinung nach nicht als akzeptierte Antwort markiert werden. Der lexikalische Geltungsbereich speziell in JS ist anders

388voto

Pierre Spring Punkte 10020

Versuchen wir die kürzestmögliche Definition:

Lexikalisches Scoping definiert, wie Variablennamen in verschachtelten Funktionen aufgelöst werden: innere Funktionen enthalten den Geltungsbereich übergeordneter Funktionen, auch wenn die übergeordnete Funktion zurückgekehrt ist .

Das ist alles, was es zu sagen gibt!

58 Stimmen

Der letzte Teil: "auch wenn die übergeordnete Funktion zurückgekehrt ist" wird als Closure bezeichnet.

8 Stimmen

Versteht das Lexical Scoping & Closure in nur einem Satz. Danke!!

92voto

kta Punkte 18216
var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

Der obige Code gibt "I am just a local" zurück. Er wird nicht "Ich bin ein Global" zurückgeben. Denn die Funktion func() zählt dort, wo sie ursprünglich definiert wurde, nämlich unter dem Geltungsbereich der Funktion whatismyscope.

Es wird nicht stören, von was auch immer es aufgerufen wird (den globalen Bereich / von einer anderen Funktion selbst), deshalb globalen Bereich Wert, den ich bin global wird nicht gedruckt werden.

Dies wird als lexikalisches Scoping bezeichnet, wobei " Funktionen werden unter Verwendung der Umfangskette ausgeführt, die zum Zeitpunkt ihrer Definition in Kraft war. " - gemäß dem JavaScript Definition Guide.

Lexikalische Reichweite ist ein sehr mächtiges Konzept.

Ich hoffe, das hilft :)

8 Stimmen

Es sehr schöne Erklärung möchte ich eine weitere Sache hinzufügen, wenn Sie schreiben Funktion func() {return this.scope;} dann wird es zurückgeben "Ich bin global" verwenden Sie einfach dieses Schlüsselwort und Ihr Bereich wird geändert werden

55voto

Evan Meagher Punkte 4307

Lexikalisches (AKA statisches) Scoping bezieht sich auf die Bestimmung des Geltungsbereichs einer Variablen ausschließlich auf der Grundlage ihrer Position innerhalb des Textkorpus des Codes. Eine Variable bezieht sich immer auf ihre Top-Level-Umgebung. Es ist gut, dies zu verstehen in Verhältnis zum dynamischen Geltungsbereich.

50voto

Ralph M. Rickenbach Punkte 12431

Der Geltungsbereich definiert den Bereich, in dem Funktionen, Variablen usw. verfügbar sind. Die Verfügbarkeit einer Variablen wird beispielsweise durch den Kontext definiert, in dem sie definiert ist, d. h. durch die Funktion, die Datei oder das Objekt, in dem sie definiert ist. Wir nennen diese Variablen gewöhnlich lokale Variablen.

Der lexikalische Teil bedeutet, dass Sie den Anwendungsbereich aus dem Lesen des Quellcodes ableiten können.

Der lexikalische Geltungsbereich wird auch als statischer Geltungsbereich bezeichnet.

Der dynamische Geltungsbereich definiert globale Variablen, die nach ihrer Definition von überall her aufgerufen oder referenziert werden können. Manchmal werden sie auch als globale Variablen bezeichnet, obwohl globale Variablen in den meisten Programmiersprachen einen lexikalischen Geltungsbereich haben. Das bedeutet, dass aus dem Lesen des Codes abgeleitet werden kann, dass die Variable in diesem Kontext verfügbar ist. Vielleicht muss man einer uses- oder includes-Klausel folgen, um die Instatinierung oder Definition zu finden, aber der Code/Compiler kennt die Variable an dieser Stelle.

Beim dynamischen Scoping hingegen suchen Sie zuerst in der lokalen Funktion, dann in der Funktion, die die lokale Funktion aufgerufen hat, dann in der Funktion, die diese Funktion aufgerufen hat, und so weiter, den Aufrufstapel hinauf. "Dynamisch" bezieht sich auf Veränderungen, da der Aufrufstapel bei jedem Aufruf einer bestimmten Funktion anders sein kann, so dass die Funktion auf unterschiedliche Variablen treffen kann, je nachdem, von wo aus sie aufgerufen wird. (siehe aquí )

Ein interessantes Beispiel für einen dynamischen Geltungsbereich finden Sie unter aquí .

Für weitere Einzelheiten siehe aquí y aquí .

Einige Beispiele in Delphi/Object Pascal

Delphi hat lexikalischen Umfang.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type 
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

Am nächsten kommt Delphi dem dynamischen Bereich mit dem Funktionspaar RegisterClass()/GetClass(). Für seine Verwendung siehe aquí .

Angenommen, der Zeitpunkt, zu dem RegisterClass([TmyClass]) aufgerufen wird, um eine bestimmte Klasse zu registrieren, kann nicht durch Lesen des Codes vorhergesagt werden (er wird in einer vom Benutzer aufgerufenen Schaltflächen-Klick-Methode aufgerufen); Code, der GetClass('TmyClass') aufruft, wird ein Ergebnis erhalten oder nicht. Der Aufruf von RegisterClass() muss nicht im lexikalischen Bereich der Einheit liegen, die GetClass() verwendet;

Eine weitere Möglichkeit für einen dynamischen Geltungsbereich sind anonyme Verfahren (Closures) in Delphi 2009, da sie die Variablen ihrer aufrufenden Funktion kennen. Sie folgen dem Aufrufpfad von dort aus nicht rekursiv und sind daher nicht vollständig dynamisch.

2 Stimmen

Auf private kann in der gesamten Einheit, in der die Klasse definiert ist, zugegriffen werden. Aus diesem Grund wurde in D2006 "Strict private" eingeführt.

4 Stimmen

+1 für einfache Sprache (im Gegensatz zu sowohl komplizierter Sprache als auch Beispielen ohne viel Beschreibung)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X