Home ┬╗ Top debug print New

Top debug print New

by Tratamien Torosace

You are viewing this post: Top debug print New

Neues Update zum Thema debug print


Table of Contents

Print method (Visual Basic for Applications) | Microsoft Docs Aktualisiert

13/9/2021┬á┬Ě Example. Using the Print method, this example displays the value of the variable MyVar in the Immediate window. Note that the Print method only applies to objects that can display text.. Dim MyVar MyVar = “Come see me in the Immediate pane.” Debug.Print MyVar See also. Objects (Visual Basic for Applications)

+ ausf├╝hrliche Artikel hier sehen

Read more

Inhaltsverzeichnis

Druckverfahren

Artikel

30.03.2022

2 Minuten zu lesen

8 Mitwirkende Ist diese Seite hilfreich? Ja Nein Weiteres Feedback? Feedback wird an Microsoft gesendet: Wenn Sie auf die Schaltfl├Ąche ÔÇ×SendenÔÇť klicken, wird Ihr Feedback zur Verbesserung von Microsoft-Produkten und -Diensten verwendet

Datenschutz-Bestimmungen

Senden Vielen Dank

In diesem Artikel

Druckt Text im unmittelbaren Fenster.

Syntax

Objekt.Drucken [ Ausgabeliste ]

Die Syntax der Print-Methode hat den folgenden Objektbezeichner und -teil:

Teil Beschreibungsobjekt Optional

Ein Objektausdruck, der zu einem Objekt in der Liste Gilt f├╝r ausgewertet wird

Ausgabeliste Optional

Ausdruck oder Liste der zu druckenden Ausdr├╝cke

Wenn weggelassen, wird eine Leerzeile ausgegeben

Das Argument der Ausgabeliste hat die folgende Syntax und Teile:

{Spc(n) | Tab(n)} Ausdruckszeichen

Teil Beschreibung Spc(n) Optional

Wird verwendet, um Leerzeichen in die Ausgabe einzuf├╝gen, wobei n die Anzahl der einzuf├╝genden Leerzeichen ist

Registerkarte(n) Optional

Wird verwendet, um die Einf├╝gemarke an einer absoluten Spaltennummer zu positionieren, wobei n die Spaltennummer ist

Verwenden Sie die Tabulatortaste ohne Argument, um die Einf├╝gemarke am Anfang der n├Ąchsten Druckzone zu positionieren

Ausdruck Optional

Zu druckender numerischer Ausdruck oder Zeichenfolgenausdruck

optional

Gibt den Einf├╝gepunkt f├╝r das n├Ąchste Zeichen an

Verwenden Sie ein Semikolon (;), um die Einf├╝gemarke unmittelbar nach dem letzten angezeigten Zeichen zu positionieren

Verwenden Sie Tab(n), um die Einf├╝gemarke an einer absoluten Spaltennummer zu positionieren

Verwenden Sie die Tabulatortaste ohne Argument, um die Einf├╝gemarke am Anfang der n├Ąchsten Druckzone zu positionieren

Wenn charpos weggelassen wird, wird das n├Ąchste Zeichen in der n├Ąchsten Zeile ausgegeben

Bemerkungen

Mehrere Ausdr├╝cke k├Ânnen entweder durch ein Leerzeichen oder ein Semikolon getrennt werden

Alle Daten, die in das Direktfenster gedruckt werden, werden ordnungsgem├Ą├č formatiert, indem das Dezimaltrennzeichen f├╝r die f├╝r Ihr System angegebenen Gebietsschemaeinstellungen verwendet wird

Die Schl├╝sselw├Ârter werden in der entsprechenden Sprache f├╝r die Host-Anwendung ausgegeben

Bei booleschen Daten wird entweder True oder False ausgegeben

Die Schl├╝sselw├Ârter True und False werden gem├Ą├č der Gebietsschemaeinstellung f├╝r die Hostanwendung ├╝bersetzt

Datumsdaten werden unter Verwendung des von Ihrem System erkannten kurzen Standarddatumsformats geschrieben

Wenn entweder die Datums- oder die Zeitkomponente fehlt oder Null ist, werden nur die bereitgestellten Daten geschrieben

Wenn die Ausgabelistendaten leer sind, wird nichts geschrieben

Wenn die Ausgabelistendaten jedoch Null sind, wird Null ausgegeben

Das Schl├╝sselwort Null wird bei der Ausgabe entsprechend ├╝bersetzt

Bei Fehlerdaten wird die Ausgabe als Error errorcode geschrieben

Das Schl├╝sselwort Error wird bei der Ausgabe entsprechend ├╝bersetzt

Das Objekt ist erforderlich, wenn die Methode au├čerhalb eines Moduls mit einem Standardanzeigebereich verwendet wird

Beispielsweise tritt ein Fehler auf, wenn die Methode in einem Standardmodul aufgerufen wird, ohne ein Objekt anzugeben, aber wenn sie in einem Formularmodul aufgerufen wird, wird eine Ausgabeliste auf dem Formular angezeigt

Hinweis Da die Methode Print normalerweise mit Zeichen mit proportionalen Abst├Ąnden druckt, Es besteht keine Korrelation zwischen der Anzahl der gedruckten Zeichen und der Anzahl der Spalten mit fester Breite, die diese Zeichen belegen

Beispielsweise nimmt ein breiter Buchstabe wie etwa ein ÔÇ×WÔÇť mehr als eine Spalte mit fester Breite ein, und ein schmaler Buchstabe wie etwa ein ÔÇ×iÔÇť nimmt weniger ein

Um F├Ąlle zu ber├╝cksichtigen, in denen ├╝berdurchschnittlich breite Zeichen verwendet werden, m├╝ssen Ihre Tabellenspalten weit genug voneinander entfernt positioniert werden

Alternativ k├Ânnen Sie auch mit einer Schriftart mit festem Zeichenabstand (z

B

Courier) drucken, um sicherzustellen, dass jedes Zeichen nur eine Spalte belegt

Beispiel

Dieses Beispiel zeigt mithilfe der Print-Methode den Wert der Variablen MyVar im Direktfenster an

Beachten Sie, dass die Print-Methode nur f├╝r Objekte gilt, die Text anzeigen k├Ânnen

Dim MyVar MyVar = “Besuchen Sie mich im Direktbereich.” Debug.Print MyVar

Also siehe

Unterst├╝tzung und Feedback

Haben Sie Fragen oder Feedback zu Office VBA oder dieser Dokumentation? Unter Office VBA-Support und -Feedback finden Sie Anleitungen dazu, wie Sie Support erhalten und Feedback geben k├Ânnen.

Excel VBA – How to Debug.Print to File New Update

Video unten ansehen

Weitere hilfreiche Informationen im Thema anzeigen debug print

debug print Einige Bilder im Thema

 Update Excel VBA - How to Debug.Print to File
Excel VBA – How to Debug.Print to File New

GitHub – gruns/icecream: ­čŹŽ Never use print() to debug again. Update New

15/2/2018┬á┬Ě IceCream ÔÇö Never use print() to debug again. Do you ever use print() or log() to debug your code? Of course you do. IceCream, or ic for short, makes print debugging a little sweeter.. ic() is like print(), but better: It prints both expressions/variable names and their values.

+ ausf├╝hrliche Artikel hier sehen

Read more

IceCream ÔÇô Verwenden Sie nie wieder print() zum Debuggen

Verwenden Sie jemals print() oder log(), um Ihren Code zu debuggen? Nat├╝rlich tust du

IceCream, oder kurz ic, macht das Debuggen von Drucken etwas s├╝├čer

ic() ist wie print() , aber besser:

Es gibt sowohl Ausdr├╝cke/Variablennamen als auch ihre Werte aus

Es ist 40 % schneller zu tippen

Datenstrukturen sind ziemlich gedruckt

Die Ausgabe ist syntaxhervorgehoben

Es enth├Ąlt optional den Programmkontext: Dateiname, Zeilennummer und ├╝bergeordnete Funktion

IceCream ist gut getestet, freiz├╝gig lizenziert und unterst├╝tzt Python 2, Python 3, PyPy2 und PyPy3

Variablen untersuchen

Haben Sie jemals Variablen oder Ausdr├╝cke ausgegeben, um Ihr Programm zu debuggen? Wenn Sie jemals so etwas getippt haben

print ( foo ( ‘123’ ))

oder je gr├╝ndlicher

print ( “foo(‘123’)” , foo (‘123’ ))

dann ist ic() hier, um zu helfen

Bei Argumenten pr├╝ft ic() sich selbst und gibt sowohl seine eigenen Argumente als auch die Werte dieser Argumente aus

from icecream import ic def foo ( i ): return i + 333 ic ( foo ( 123 ))

druckt ic| foo(123): 456

Ebenso

d = { ‘Schl├╝ssel’ : { 1 : ‘eins’ }} ic ( d [ ‘Schl├╝ssel’ ][ 1 ]) class klass (): attr = ‘yep’ ic ( klass

attr )

druckt ic| d[‘Schl├╝ssel’][1]: ‘eins’ ic| class.attr: ‘ja’

Geben Sie einfach ic() eine Variable oder einen Ausdruck und Sie sind fertig

Einfach

Ausf├╝hrung pr├╝fen

Haben Sie jemals print() verwendet, um festzustellen, welche Teile Ihres Programms ausgef├╝hrt werden und in welcher Reihenfolge sie ausgef├╝hrt werden? Wenn Sie zum Beispiel jemals Druckanweisungen zum Debuggen von Code hinzugef├╝gt haben, wie z

def foo (): print ( 0 ) first () wenn Ausdruck : print ( 1 ) second () else : print ( 2 ) Third ()

dann hilft auch hier ic()

Ohne Argumente pr├╝ft ic() sich selbst und gibt den aufrufenden Dateinamen, die Zeilennummer und die ├╝bergeordnete Funktion aus

from icecream import ic def foo (): ic () first () if expression : ic () second () else : ic ( ) Dritter()

druckt ic| example.py:4 in foo() ic| example.py:11 in foo()

Einfach ic() aufrufen und fertig

Einfach

R├╝ckgabewert

ic() gibt seine Argumente zur├╝ck, sodass ic() einfach in bereits bestehenden Code eingef├╝gt werden kann

>>> a = 6 >>> def half ( i ): >>> return i / 2 >>> b = halb(ic(a)) ic| a: 6 >>> ic(b) ic| b: 3

Verschiedenes

ic.format(*args) ist wie ic(), aber die Ausgabe wird als String zur├╝ckgegeben, anstatt in stderr geschrieben zu werden

>>> from icecream import ic >>> s = ‘sup’ >>> out = ic.format (s) >>> drucke (aus) ic| s: ‘sup’

Au├čerdem kann die Ausgabe von ic() mit ic.disable() bzw

ic.enable() vollst├Ąndig deaktiviert und sp├Ąter wieder aktiviert werden

from icecream import ic ic ( 1 ) ic

deaktivieren () ic ( 2 ) ic

aktivieren () ic ( 3 )

druckt ic| 1: 1ic| 3: 3

ic() gibt nat├╝rlich weiterhin seine Argumente zur├╝ck, wenn es deaktiviert ist; kein vorhandener Code mit ic() bricht

Tricks importieren

Um ic() in jeder Datei verf├╝gbar zu machen, ohne dass es in jede Datei importiert werden muss, k├Ânnen Sie es installieren()

Zum Beispiel in einem Stammverzeichnis A.py :

#!/usr/bin/env python3 # -*- Codierung: utf-8 -*- from icecream import install install () from B import foo foo ()

und dann in B.py , das von A.py importiert wird, rufen Sie einfach ic() : auf

# -*- Codierung: utf-8 -*- def foo (): x = 3 ic ÔÇőÔÇőÔÇőÔÇő( x )

install() f├╝gt ic() zum builtins-Modul hinzu, das von allen vom Interpreter importierten Dateien geteilt wird

In ├Ąhnlicher Weise kann ic() sp├Ąter auch deinstalliert werden

Zu diesem Zweck kann sich dieses Fallback-Import-Snippet als n├╝tzlich erweisen:

try : from icecream import ic au├čer ImportError : # Graceful Fallback, wenn IceCream nicht installiert ist

ic = lambda * a : None if not a else ( a [ 0 ] if len ( a ) == 1 else a ) # noqa

Aufbau

ic.configureOutput(prefix, outputFunction, argToStringFunction, includeContext) kann verwendet werden, um ein benutzerdefiniertes Ausgabepr├Ąfix anzunehmen (der Standardwert ist ic| ), die Ausgabefunktion zu ├Ąndern (standardm├Ą├čig wird in stderr geschrieben), angepasst, wie Argumente in Zeichenfolgen serialisiert werden, und/oder f├╝gen Sie den Kontext des ic()-Aufrufs (Dateiname, Zeilennummer und ├╝bergeordnete Funktion) in die ic()-Ausgabe mit Argumenten ein

>>> from icecream import ic >>> ic.configureOutput( prefix = ‘hello ->’ ) >>> ic( ‘Welt’ ) Hallo -> ‘Welt’

prefix kann optional auch eine Funktion sein.

>>> import time >>> from icecream import ic >>> >>> def unixTimestamp (): >>> return ‘ %i |> ‘ % int (time.time( )) >>> >>> ic.configureOutput( prefix = unixTimestamp) >>> ic( ‘world’ ) 1519185860 |> ‘world’: ‘world’

outputFunction , sofern vorhanden, wird mit der Ausgabe von ic() aufgerufen, anstatt dass diese Ausgabe in stderr geschrieben wird (Standardeinstellung)

>>> Protokollierung importieren >>> from icecream import ic >>> >>> def warn ( s ): >>> Protokollierung.Warnung(en) >>> >>> ic.configureOutput( outputFunction = warn) >>> ic( ‘eep’ ) WARNING:root:ic| ‘eep’: ‘eep’

argToStringFunction , sofern vorhanden, wird mit Argumentwerten aufgerufen, die in anzeigbare Zeichenfolgen serialisiert werden sollen

Der Standardwert ist pprint.pformat() von PrettyPrint, aber dies kann ge├Ąndert werden, um beispielsweise nicht standardm├Ą├čige Datentypen auf benutzerdefinierte Weise zu behandeln

>>> from icecream import ic >>> >>> def toString ( obj ): >>> if isinstance (obj, str ): >>> return ‘ [!string %r with length %i !] ‘ % (obj, len (obj)) >>> return repr (obj) >>> >> > ic.configureOutput( argToStringFunction = toString) >>> ic( 7 , ‘Hallo’ ) ic| 7: 7, ‘hello’: [!String ‘hallo’ mit L├Ąnge 5!]

Die standardm├Ą├čige argToStringFunction ist icecream.argumentToString und verf├╝gt ├╝ber Methoden zum Registrieren und Aufheben der Registrierung von Funktionen, die f├╝r bestimmte Klassen mit functools.singledispatch versendet werden sollen

Es hat auch eine Registrierungseigenschaft, um registrierte Funktionen anzuzeigen

np.ndarray) >>> def _ ( obj ): >>> return f ” ndarray, shape= { obj.shape } , dtype= { obj.dtype } ” >>> >>> x = np.zeros(( 1 , 2 )) >>> ic(x) ic| x: ndarray, shape=(1, 2), dtype=float64 >>> >>> # Registrierte Funktionen anzeigen >>> argumentToString.registry mappingproxy({object: , numpy

ndarray: }) >>> >>> # Registrierung einer Funktion aufheben und auf das Standardverhalten zur├╝ckgreifen >>> argumentToString.unregister(np.ndarray) >>> ic(x) ic| x: array([[0., 0.]])

includeContext , sofern angegeben und True, f├╝gt den Dateinamen, die Zeilennummer und die ├╝bergeordnete Funktion des ic() -Aufrufs zur Ausgabe von ic() hinzu

>>> from icecream import ic >>> ic.configureOutput( includeContext = True ) >> > >>> def foo (): >>> ic( ‘ str ‘ ) >>> foo() ic| example.py:12 in foo()- ‘str’: ‘str’

includeContext ist standardm├Ą├čig False.

Installation

Die Installation von IceCream mit pip ist einfach

$ pip install icecream

Zugeh├Ârige Python-Bibliotheken

ic() verwendet die Ausf├╝hrung durch @alexmojaki, um ic()-Aufrufe im Python-Quellcode zuverl├Ąssig zu lokalisieren

Es ist magisch.

IceCream in anderen Sprachen

Leckeres Eis sollte man in jeder Sprache genie├čen.

Excel VBA Tutorial 1 Basics – Setup, Debug.Print, Msgbox Update

Video unten ansehen

Neues Update zum Thema debug print

debug print Einige Bilder im Thema

 Update Excel VBA Tutorial 1 Basics - Setup, Debug.Print, Msgbox
Excel VBA Tutorial 1 Basics – Setup, Debug.Print, Msgbox New Update

Debug your app | Android Developers New

24/3/2022┬á┬Ě Note: Remove debug log messages and stack trace print calls from your code when you are ready to publish your app. You could do this by setting a DEBUG flag and placing debug log messages inside conditional statements.. View the system log. You can view and filter debug and other system messages in the Logcat window. For example, you can see messages when ÔÇŽ

+ mehr hier sehen

Read more

Android Studio bietet einen Debugger, mit dem Sie Folgendes und mehr tun k├Ânnen:

Diese Seite enth├Ąlt Anweisungen f├╝r grundlegende Debugger-Operationen

Weitere Dokumentation finden Sie auch in den Debugging-Dokumenten zu IntelliJ IDEA

Bevor Sie mit dem Debuggen beginnen k├Ânnen, m├╝ssen Sie sich wie folgt vorbereiten:

Wenn Ihre App von einem Bibliotheksmodul abh├Ąngt, das Sie ebenfalls debuggen m├Âchten, muss diese Bibliothek auch mit debugable true gepackt werden, damit sie ihre Debugsymbole beibeh├Ąlt

Um sicherzustellen, dass die debuggbaren Varianten Ihres App-Projekts die debuggbare Variante eines Bibliotheksmoduls erhalten, stellen Sie sicher, dass Sie nicht standardm├Ą├čige Versionen Ihrer Bibliothek ver├Âffentlichen.

Diese Eigenschaft gilt auch f├╝r Module mit C/C++-Code

(Die Eigenschaft jniDebuggable wird nicht mehr verwendet.) Sie m├╝ssen eine Build-Variante verwenden, die debuggable true in der Build-Konfiguration enth├Ąlt

Normalerweise k├Ânnen Sie einfach die standardm├Ą├čige ÔÇ×DebugÔÇť-Variante ausw├Ąhlen, die in jedem Android Studio-Projekt enthalten ist (auch wenn sie in der build.gradle-Datei nicht sichtbar ist)

Aber wenn Sie neue Build-Typen definieren, die debugf├Ąhig sein sollen, m├╝ssen Sie `debuggable true` zum Build-Typ hinzuf├╝gen:

Wenn Sie den Emulator verwenden, ist dieser standardm├Ą├čig aktiviert

Aber f├╝r ein verbundenes Ger├Ąt m├╝ssen Sie das Debugging in den Ger├Ąteentwickleroptionen aktivieren

Sie k├Ânnen eine Debugging-Sitzung wie folgt starten:

Abbildung 1

Das Debugger-Fenster mit dem aktuellen Thread und dem Objektbaum f├╝r eine Variable

Andernfalls erstellt Android Studio ein APK, signiert es mit einem Debug-Schl├╝ssel, installiert es auf Ihrem ausgew├Ąhlten Ger├Ąt und f├╝hrt es aus

Wenn Sie Ihrem Projekt C- und C++-Code hinzuf├╝gen , f├╝hrt Android Studio auch den LLDB-Debugger im Debug-Fenster aus, um Ihren nativen Code zu debuggen Die App wird bereits auf dem Ger├Ąt ausgef├╝hrt und wird neu gestartet, um mit dem Debuggen zu beginnen

Wenn Sie lieber dieselbe Instanz der App weiter ausf├╝hren m├Âchten, klicken Sie auf Debuggen abbrechen und h├Ąngen Sie stattdessen den Debugger an eine laufende App an

Wenn Ihre App bereits auf Ihrem Ger├Ąt ausgef├╝hrt wird, k├Ânnen Sie wie folgt mit dem Debuggen beginnen, ohne Ihre App neu zu starten:

Aus dem Drop-down-Men├╝ Android-Debuggereinstellungen verwenden aus k├Ânnen Sie eine vorhandene Ausf├╝hrungs-/Debugkonfiguration ausw├Ąhlen

(F├╝r C- und C++-Code k├Ânnen Sie so die LLDB-Startbefehle, LLDB-Post-Attach-Befehle und Symbolverzeichnisse in einer vorhandenen Konfiguration wiederverwenden.) Wenn Sie keine vorhandene Run/Debug-Konfiguration haben, w├Ąhlen Sie Create New

Diese Auswahl aktiviert das Dropdown-Men├╝ Debug-Typ, in dem Sie einen anderen Debug-Typ ausw├Ąhlen k├Ânnen

Standardm├Ą├čig verwendet Android Studio den Auto-Debug-Typ, um die beste Debugger-Option f├╝r Sie auszuw├Ąhlen, je nachdem, ob Ihr Projekt Java- oder C/C++-Code enth├Ąlt

Wenn Sie einen Emulator oder ein gerootetes Ger├Ąt verwenden, k├Ânnen Sie Alle anzeigen aktivieren Prozesse, um alle Prozesse anzuzeigen

Hinweis: Der Debugger und Garbage Collector von Android Studio sind lose integriert

Die virtuelle Android-Maschine garantiert, dass jedes Objekt, das dem Debugger bekannt ist, erst dann von Garbage Collection erfasst wird, nachdem der Debugger die Verbindung getrennt hat

Dies kann im Laufe der Zeit zu einer Anh├Ąufung von Objekten f├╝hren, w├Ąhrend der Debugger verbunden ist

Wenn der Debugger zum Beispiel einen laufenden Thread sieht, wird das zugeh├Ârige Thread-Objekt nicht von der Garbage Collection erfasst, bis der Debugger die Verbindung trennt, selbst wenn der Thread beendet wurde

Da zum Debuggen von Java/Kotlin-Code und C/C++-Code verschiedene Debugger-Tools erforderlich sind, Mit dem Android Studio-Debugger k├Ânnen Sie ausw├Ąhlen, welcher Debugger-Typ verwendet werden soll

Standardm├Ą├čig entscheidet Android Studio, welcher Debugger verwendet werden soll, basierend auf den Sprachen, die es in Ihrem Projekt erkennt (mit dem Auto-Debugger-Typ)

Sie k├Ânnen den Debugger jedoch manuell in der Debug-Konfiguration ausw├Ąhlen (klicken Sie auf Ausf├╝hren > Konfigurationen bearbeiten) oder in dem Dialogfeld, das angezeigt wird, wenn Sie auf Ausf├╝hren > Debugger an Android-Prozess anh├Ąngen klicken

Die verf├╝gbaren Debug-Typen umfassen die folgenden:

Automobil

W├Ąhlen Sie diesen Debug-Typ aus, wenn Android Studio automatisch die beste Option f├╝r den zu debuggenden Code ausw├Ąhlen soll

Wenn Sie beispielsweise C- oder C++-Code in Ihrem Projekt haben, verwendet Android Studio automatisch den Dual-Debug-Typ

Andernfalls verwendet Android Studio den Java-Debug-Typ.

Java

W├Ąhlen Sie diesen Debug-Typ aus, wenn Sie nur in Java oder Kotlin geschriebenen Code debuggen m├Âchten ÔÇô der Java-Debugger ignoriert alle Haltepunkte oder ├ťberwachungen, die Sie in Ihrem nativen Code festlegen

Native (nur mit C/C++-Code verf├╝gbar)

W├Ąhlen Sie diesen Debug-Typ aus, wenn Sie nur LLDB zum Debuggen Ihres Codes verwenden m├Âchten

Bei Verwendung dieses Debug-Typs ist die Sitzungsansicht des Java-Debuggers nicht verf├╝gbar

Standardm├Ą├čig untersucht LLDB nur Ihren nativen Code und ignoriert Breakpoints in Ihrem Java-Code

Wenn Sie auch Ihren Java-Code debuggen m├Âchten, sollten Sie entweder zum Auto- oder Dual-Debug-Typ wechseln

Natives Debuggen funktioniert nur auf Ger├Ąten, die die folgenden Anforderungen erf├╝llen: Das Ger├Ąt unterst├╝tzt run-as

Um zu ├╝berpr├╝fen, ob das Ger├Ąt run-as unterst├╝tzt, f├╝hren Sie den folgenden Befehl auf der ADB-Shell aus, die mit Ihrem Ger├Ąt verbunden ist: run-as your-package-name pwd Ersetzen Sie your-package-name durch den Paketnamen Ihrer App

Wenn das Ger├Ąt run-as unterst├╝tzt, sollte der Befehl ohne Fehler zur├╝ckgegeben werden

Auf dem Ger├Ąt ist ptrace aktiviert

Um zu ├╝berpr├╝fen, ob Ptrace aktiviert ist, f├╝hren Sie den folgenden Befehl auf der ADB-Shell aus, die mit Ihrem Ger├Ąt verbunden ist: sysctl kernel.yama.ptrace_scope Wenn Ptrace aktiviert ist, gibt der Befehl den Wert 0 oder einen unbekannten Schl├╝sselfehler aus

Wenn ptrace nicht aktiviert ist, wird es einen anderen Wert als 0.

Dual (nur mit C/C++-Code verf├╝gbar) ausgeben

W├Ąhlen Sie diesen Debug-Typ aus, wenn Sie zwischen dem Debuggen von Java und nativem Code wechseln m├Âchten

Android Studio f├╝gt sowohl den Java-Debugger als auch LLDB an Ihren App-Prozess an, einen f├╝r den Java-Debugger und einen f├╝r LLDB, sodass Sie Breakpoints sowohl in Ihrem Java- als auch in Ihrem nativen Code ├╝berpr├╝fen k├Ânnen, ohne Ihre App neu zu starten oder Ihre Debug-Konfiguration zu ├Ąndern

Beachten Sie in Abbildung 2 die beiden Registerkarten rechts neben dem Titel des Debug-Fensters

Da die App sowohl Java- als auch C++-Code enth├Ąlt, dient eine Registerkarte zum Debuggen des nativen Codes und die andere zum Debuggen des Java-Codes, wie durch -java angegeben

Abbildung 2

Registerkarte zum Debuggen von nativem Code und Registerkarte zum Debuggen von Java-Code

Hinweis: Wenn Sie nativen Code debuggen, der vom Compiler optimiert wurde, erhalten Sie m├Âglicherweise die folgende Warnmeldung: Diese Funktion wurde mit aktivierten Optimierungen kompiliert

Einige Debugger-Funktionen sind m├Âglicherweise nicht verf├╝gbar

Bei der Verwendung von Optimierungsflags, wie z

B

-O-Flags, nimmt der Compiler Änderungen an Ihrem kompilierten Code vor, damit er effizienter ausgeführt wird

Dies kann dazu f├╝hren, dass der Debugger unerwartete oder falsche Informationen meldet, da es f├╝r den Debugger schwierig ist, den optimierten kompilierten Code wieder dem urspr├╝nglichen Quellcode zuzuordnen

Aus diesem Grund sollten Sie Compiler-Optimierungen deaktivieren, w├Ąhrend Sie Ihren nativen Code debuggen

Verwenden Sie das Systemprotokoll

Das Systemprotokoll zeigt Systemmeldungen an, w├Ąhrend Sie Ihre App debuggen

Diese Nachrichten enthalten Informationen von Apps, die auf dem Ger├Ąt ausgef├╝hrt werden

Wenn Sie das Systemprotokoll zum Debuggen Ihrer App verwenden m├Âchten, stellen Sie sicher, dass Ihr Code Protokollmeldungen schreibt und den Stack-Trace f├╝r Ausnahmen druckt, w├Ąhrend sich Ihre App in der Entwicklungsphase befindet

Schreiben Sie Protokollmeldungen in Ihren Code

Um Protokollmeldungen in Ihren Code zu schreiben, verwenden Sie die Log-Klasse

Protokollmeldungen helfen Ihnen, den Ausf├╝hrungsablauf zu verstehen, indem sie die Systemdebugausgabe erfassen, w├Ąhrend Sie mit Ihrer App interagieren

Protokollmeldungen k├Ânnen Ihnen mitteilen, welcher Teil Ihrer Anwendung fehlgeschlagen ist

Weitere Informationen zur Protokollierung finden Sie unter Protokolle schreiben und anzeigen

Das folgende Beispiel zeigt, wie Sie Protokollmeldungen hinzuf├╝gen k├Ânnen, um festzustellen, ob Informationen zum vorherigen Status verf├╝gbar sind, wenn Ihre Aktivit├Ąt beginnt:

Kotlin import android.util.Log. .

private val TAG: String = MyActivity::class.java.simpleName. .

class MyActivity : Activity() {. .

override fun onCreate(savedInstanceState: Bundle?) {. .

if (savedInstanceState != null) { Log.d(TAG, “onCreate() Wiederherstellung des vorherigen Zustands”) /* Zustand wiederherstellen */ } else { Log.d(TAG, “onCreate() Kein gespeicherter Zustand verf├╝gbar”) /* App initialisieren */ } } } Java-Import android.util.Log;. .

├Âffentliche Klasse MyActivity erweitert Activity { private static final String TAG = MyActivity.class.getSimpleName();. .

@Override public void onCreate(Bundle savedInstanceState) {. .

if (savedInstanceState != null) { Log.d(TAG, “onCreate() Restoring previous state”); /* Status wiederherstellen */ } else { Log.d(TAG, “onCreate() Kein gespeicherter Status verf├╝gbar”); /* Anwendung initialisieren */ } } }

W├Ąhrend der Entwicklung kann Ihr Code auch Ausnahmen abfangen und den Stack-Trace in das Systemprotokoll schreiben:

Kotlin fun someOtherMethod() { try {. .

} catch (e : SomeException) { Log.d(TAG, “someOtherMethod()”, e) } } Java void someOtherMethod() { try {. .

} catch (SomeException e) {Log.d(TAG, “someOtherMethod()”, e); } }

Hinweis: Entfernen Sie Debug-Protokollmeldungen und Stack-Trace-Druckaufrufe aus Ihrem Code, wenn Sie bereit sind, Ihre App zu ver├Âffentlichen

Sie k├Ânnen dies tun, indem Sie ein DEBUG-Flag setzen und Debug-Protokollmeldungen in bedingte Anweisungen einf├╝gen

Sehen Sie sich das Systemprotokoll an

Sie k├Ânnen Debug- und andere Systemmeldungen im Logcat-Fenster anzeigen und filtern

Beispielsweise k├Ânnen Sie Meldungen anzeigen, wenn Garbage Collection stattfindet, oder Meldungen, die Sie Ihrer App mit der Log-Klasse hinzuf├╝gen

Um Logcat zu verwenden, starten Sie das Debuggen und w├Ąhlen Sie die Registerkarte Logcat in der unteren Symbolleiste aus, wie in Abbildung 3 gezeigt

Abbildung 3. Logcat-Fenster mit Filtereinstellungen

Eine Beschreibung von logcat und seinen Filteroptionen finden Sie unter Protokolle mit Logcat schreiben und anzeigen

Mit Haltepunkten arbeiten

Android Studio unterst├╝tzt mehrere Arten von Haltepunkten, die verschiedene Debugging-Aktionen ausl├Âsen

Der h├Ąufigste Typ ist ein Zeilenhaltepunkt, der die Ausf├╝hrung Ihrer App an einer bestimmten Codezeile anh├Ąlt

W├Ąhrend der Pause k├Ânnen Sie Variablen untersuchen, Ausdr├╝cke auswerten und dann die Ausf├╝hrung Zeile f├╝r Zeile fortsetzen, um die Ursachen von Laufzeitfehlern zu ermitteln

Um einen Zeilenhaltepunkt hinzuzuf├╝gen, gehen Sie wie folgt vor:

Suchen Sie die Codezeile, in der Sie die Ausf├╝hrung anhalten m├Âchten, klicken Sie dann entweder auf den linken Rand entlang dieser Codezeile oder platzieren Sie das Caretzeichen auf der Zeile und dr├╝cken Sie Strg+F8 (auf Mac, Befehlstaste+F8)

Wenn Ihre App bereits ausgef├╝hrt wird, m├╝ssen Sie sie nicht aktualisieren, um den Haltepunkt hinzuzuf├╝gen ÔÇô klicken Sie einfach auf Debugger an Android-Prozess anh├Ąngen

Starten Sie andernfalls das Debuggen, indem Sie auf Debuggen klicken

Abbildung 3

Ein roter Punkt erscheint neben der Zeile, wenn Sie einen Haltepunkt setzen

Wenn Ihre Codeausf├╝hrung den Haltepunkt erreicht, h├Ąlt Android Studio die Ausf├╝hrung Ihrer App an

Sie k├Ânnen dann die Tools auf der Registerkarte ÔÇ×DebuggerÔÇť verwenden, um den Status der App zu ermitteln:

Um den Objektbaum auf eine Variable zu untersuchen, erweitern Sie ihn in der Variablenansicht

Wenn die Variablenansicht nicht sichtbar ist, klicken Sie auf Variablenansicht wiederherstellen.

Um einen Ausdruck am aktuellen Ausf├╝hrungspunkt auszuwerten, klicken Sie auf Ausdruck auswerten.

Um zur n├Ąchsten Zeile im Code zu gelangen (ohne eine Methode einzugeben), klicken Sie auf ├ťberspringen.

Um zur ersten Zeile innerhalb eines Methodenaufrufs zu gelangen, klicken Sie auf Step Into.

Um zur n├Ąchsten Zeile au├čerhalb der aktuellen Methode zu gelangen, klicken Sie auf Step Out.

Um die App normal weiter auszuf├╝hren, klicken Sie auf Resume Program

Code, f├╝gt der Auto-Debug-Typ standardm├Ą├čig sowohl den Java-Debugger als auch LLDB als zwei separate Prozesse an Ihre App an, sodass Sie zwischen der ├ťberpr├╝fung von Java- und C/C++-Breakpoints wechseln k├Ânnen, ohne Ihre App neu zu starten oder Einstellungen zu ├Ąndern

Hinweis: F├╝r Android Studio zu Breakpoints in Ihrem C- oder C++-Code erkennen, m├╝ssen Sie einen Debug-Typ verwenden, der LLDB unterst├╝tzt, z

B

Auto, Native oder Dual

Sie k├Ânnen den von Android Studio verwendeten Debug-Typ ├Ąndern, indem Sie Ihre Debug-Konfiguration bearbeiten

Um mehr ├╝ber die verschiedenen Debug-Typen zu erfahren, lesen Sie den Abschnitt ├╝ber die Verwendung anderer Debug-Typen.

Wenn Android Studio Ihre App auf Ihrem Zielger├Ąt bereitstellt, wird das Debug-Fenster mit einer Registerkarte oder Debug-Sitzungsansicht f├╝r jeden Debugger-Prozess ge├Âffnet, wie in Abbildung 4 dargestellt

Abbildung 4

Debuggen von nativem Code mit LLDB

Android Studio wechselt zur Registerkarte , wenn der LLDB-Debugger auf einen Haltepunkt in Ihrem C/C++-Code st├Â├čt

Die Bereiche ÔÇ×FramesÔÇť, ÔÇ×VariablesÔÇť und ÔÇ×WatchesÔÇť sind ebenfalls verf├╝gbar und funktionieren genauso wie beim Debuggen von Java-Code

Obwohl der Bereich ÔÇ×ThreadsÔÇť in der LLDB-Sitzungsansicht nicht verf├╝gbar ist, k├Ânnen Sie ├╝ber die Dropdown-Liste im Bereich ÔÇ×FramesÔÇť auf Ihre App-Prozesse zugreifen

Sie k├Ânnen mehr ├╝ber diese Bereiche in den Abschnitten ├╝ber das Debuggen von Fensterrahmen und das Untersuchen von Variablen erfahren

Hinweis: Beim Untersuchen eines Haltepunkts in Ihrem nativen Code h├Ąlt das Android-System die virtuelle Maschine an, auf der der Java-Bytecode Ihrer App ausgef├╝hrt wird

Dies bedeutet, dass Sie nicht mit dem Java-Debugger interagieren oder Statusinformationen aus Ihrer Java-Debugger-Sitzung abrufen k├Ânnen, w├Ąhrend Sie einen Haltepunkt in Ihrem nativen Code untersuchen

Android Studio wechselt zur Registerkarte -java, wenn der Java-Debugger auf einen Haltepunkt in Ihrem Java-Code st├Â├čt

Beim Debuggen mit LLDB k├Ânnen Sie das LLDB-Terminal in der LLDB-Sitzungsansicht verwenden, um Befehlszeilenoptionen an LLDB zu ├╝bergeben

Wenn Sie bestimmte Befehle haben, die LLDB jedes Mal ausf├╝hren soll, wenn Sie mit dem Debuggen Ihrer App beginnen, entweder kurz bevor oder kurz nachdem der Debugger an Ihren App-Prozess angeh├Ąngt wird, k├Ânnen Sie diese Befehle zu Ihrer Debug-Konfiguration hinzuf├╝gen

W├Ąhrend des Debuggens von C/C++ code k├Ânnen Sie auch spezielle Arten von Breakpoints, sogenannte Watchpoints, festlegen, die Ihren App-Prozess anhalten k├Ânnen, wenn Ihre App mit einem bestimmten Speicherblock interagiert

Um mehr zu erfahren, lesen Sie den Abschnitt ├╝ber das Hinzuf├╝gen von ├ťberwachungspunkten

Haltepunkte anzeigen und konfigurieren

Um alle Breakpoints anzuzeigen und Breakpoint-Einstellungen zu konfigurieren, klicken Sie auf der linken Seite des Debug-Fensters auf Breakpoints anzeigen

Das Fenster ÔÇ×BreakpointsÔÇť wird angezeigt, wie in Abbildung 5 dargestellt

Abbildung 5

Das Fenster ÔÇ×BreakpointsÔÇť listet alle aktuellen Breakpoints auf und enth├Ąlt Verhaltenseinstellungen f├╝r jeden einzelnen

Im Fenster Haltepunkte k├Ânnen Sie jeden Haltepunkt in der Liste auf der linken Seite aktivieren oder deaktivieren

Wenn ein Haltepunkt deaktiviert ist, h├Ąlt Android Studio Ihre App nicht an, wenn sie diesen Haltepunkt erreicht

W├Ąhlen Sie einen Haltepunkt aus der Liste aus, um seine Einstellungen zu konfigurieren

Sie k├Ânnen einen Haltepunkt so konfigurieren, dass er zun├Ąchst deaktiviert wird, und ihn vom System aktivieren lassen, nachdem ein anderer Haltepunkt erreicht wurde

Sie k├Ânnen auch konfigurieren, ob ein Haltepunkt deaktiviert werden soll, nachdem er erreicht wurde

Um einen Breakpoint f├╝r eine Ausnahme festzulegen, w├Ąhlen Sie Exception Breakpoints in der Liste der Breakpoints aus

Debuggen Sie Fensterrahmen

Im Debugger-Fenster k├Ânnen Sie im Bereich Frames den Stack-Frame untersuchen, der das Erreichen des aktuellen Haltepunkts verursacht hat

Auf diese Weise k├Ânnen Sie im Stapelrahmen navigieren und ihn untersuchen und auch die Liste der Threads in Ihrer Android-App ├╝berpr├╝fen

Um einen Thread auszuw├Ąhlen, verwenden Sie das Drop-down-Men├╝ der Thread-Auswahl und sehen Sie sich seinen Stapelrahmen an

Ein Klick auf die Elemente im Rahmen ├Âffnet die Quelle im Editor

Sie k├Ânnen auch die Thread-Pr├Ąsentation anpassen und den Stapelrahmen exportieren, wie in der Anleitung zu Fensterrahmen beschrieben

Variablen untersuchen

Im Debugger-Fenster k├Ânnen Sie im Bereich ÔÇ×VariablenÔÇť Variablen ├╝berpr├╝fen, wenn das System Ihre App an einem Haltepunkt stoppt und Sie einen Frame aus dem Bereich ÔÇ×FramesÔÇť ausw├Ąhlen

Im Bereich ÔÇ×VariablenÔÇť k├Ânnen Sie auch Ad-hoc-Ausdr├╝cke mit statischen Methoden und/oder Variablen auswerten, die innerhalb des ausgew├Ąhlten Frames verf├╝gbar sind

Der Bereich ÔÇ×├ťberwachungenÔÇť bietet ├Ąhnliche Funktionen, mit der Ausnahme, dass zum Bereich ÔÇ×├ťberwachungenÔÇť hinzugef├╝gte Ausdr├╝cke zwischen Debugsitzungen bestehen bleiben

Sie sollten ├ťberwachungen f├╝r Variablen und Felder hinzuf├╝gen, auf die Sie h├Ąufig zugreifen oder die einen Status bereitstellen, der f├╝r die aktuelle Debugsitzung hilfreich ist

Die Bereiche ÔÇ×VariablenÔÇť und ÔÇ×├ťberwachungenÔÇť werden wie in Abbildung 5 dargestellt angezeigt

Gehen Sie wie folgt vor, um eine Variable oder einen Ausdruck zur Liste ÔÇ×├ťberwachungenÔÇť hinzuzuf├╝gen:

Beginnen Sie mit dem Debuggen

Klicken Sie im Bereich ├ťberwachungen auf Hinzuf├╝gen

Geben Sie in das angezeigte Textfeld den Namen der Variablen oder des Ausdrucks ein, die bzw

den Sie ├╝berwachen m├Âchten, und dr├╝cken Sie dann die Eingabetaste

Um ein Element aus der ├ťberwachungsliste zu entfernen, w├Ąhlen Sie das Element aus und klicken Sie dann auf Entfernen.

Sie k├Ânnen die Elemente in neu anordnen ├ťberwachungsliste, indem Sie ein Element ausw├Ąhlen und dann auf Nach oben oder Nach unten klicken

Abbildung 6

Die Bereiche ÔÇ×VariablenÔÇť und ÔÇ×├ťberwachungenÔÇť im Debugger-Fenster

Beobachtungspunkte hinzuf├╝gen

Beim Debuggen von C/C++-Code k├Ânnen Sie spezielle Arten von Haltepunkten, so genannte Watchpoints, festlegen, die Ihren App-Prozess anhalten k├Ânnen, wenn Ihre App mit einem bestimmten Speicherblock interagiert

Wenn Sie beispielsweise zwei Zeiger auf einen Speicherblock setzen und ihm einen Watchpoint zuweisen, l├Âst der Zugriff auf diesen Speicherblock mit einem der beiden Zeiger den Watchpoint aus

In Android Studio k├Ânnen Sie w├Ąhrend der Laufzeit einen Watchpoint erstellen, indem Sie eine bestimmte Variable ausw├Ąhlen , aber LLDB weist den ├ťberwachungspunkt nur dem Speicherblock zu, den das System dieser Variablen zuweist, nicht der Variablen selbst

Dies unterscheidet sich vom Hinzuf├╝gen einer Variablen zum Bereich ÔÇ×├ťberwachungenÔÇť, mit dem Sie den Wert einer Variablen beobachten, aber Ihren App-Prozess nicht aussetzen k├Ânnen, wenn das System ihren Wert im Speicher liest oder ├Ąndert

Hinweis: Wenn Ihre app Wenn ein Prozess eine Funktion beendet und das System die Zuordnung seiner lokalen Variablen aus dem Speicher aufhebt, m├╝ssen Sie alle Watchpoints neu zuweisen, die Sie f├╝r diese Variablen erstellt haben

Um einen Watchpoint festzulegen, m├╝ssen Sie die folgenden Anforderungen erf├╝llen:

Ihr physisches Zielger├Ąt oder Ihr Emulator verwendet eine x86- oder x86_64-CPU

Wenn Ihr Ger├Ąt eine ARM-CPU verwendet, m├╝ssen Sie die Grenze der Adresse Ihrer Variablen im Speicher entweder auf 4 Bytes f├╝r 32-Bit-Prozessoren oder auf 8 Bytes f├╝r 64-Bit-Prozessoren ausrichten

Sie k├Ânnen eine Variable in Ihrem nativen Code ausrichten, indem Sie __attribute__((aligned( num_bytes ))) in der Variablendeceleration angeben, wie unten gezeigt: // F├╝r einen 64-Bit-ARM-Prozessor int my_counter __attribute__((aligned(8)));

in der Variablen Verz├Âgerung, wie unten gezeigt: Sie haben bereits drei oder weniger Watchpoints zugewiesen

Android Studio unterst├╝tzt nur bis zu vier Watchpoints auf x86- oder x86_64-Zielger├Ąten

Andere Ger├Ąte unterst├╝tzen m├Âglicherweise weniger Watchpoints

Hinweis: Wenn Sie Ihre App mit 32-Bit-ARM-ABIs debuggen, kann das Hinzuf├╝gen eines Watchpoints oder das Bewegen der Maus ├╝ber Variablen im Code, um deren Werte zu untersuchen, zu einem Absturz f├╝hren

Um das Problem zu umgehen, debuggen Sie bitte mit 64-Bit-ARM-, x86- oder x86_64-Bin├Ąrdateien

Dieses Problem wird in einer kommenden Version von Android Studio behoben

Wenn Sie die oben genannten Anforderungen erf├╝llen, k├Ânnen Sie wie folgt einen Watchpoint hinzuf├╝gen:

Navigieren Sie, w├Ąhrend Ihre App an einem Haltepunkt ausgesetzt ist, zum Bereich ÔÇ×VariablenÔÇť in Ihrer LLDB-Sitzungsansicht

Klicken Sie mit der rechten Maustaste auf eine Variable, die den Speicherblock belegt, den Sie verfolgen m├Âchten, und w├Ąhlen Sie Watchpoint hinzuf├╝gen aus

Ein Dialogfeld zum Konfigurieren Ihres ├ťberwachungspunkts wird angezeigt, wie in Abbildung 7 gezeigt Wachpunkt vorerst

Android Studio speichert Ihren Watchpoint trotzdem, sodass Sie sp├Ąter in Ihrer Debug-Sitzung darauf zugreifen k├Ânnen

Sie k├Ânnen diese Option deaktivieren, wenn Sie Android Studio anweisen m├Âchten, den Watchpoint vorerst zu ignorieren

Android Studio speichert Ihren Watchpoint weiterhin, sodass Sie sp├Ąter in Ihrer Debug-Sitzung darauf zugreifen k├Ânnen

Anhalten: Standardm├Ą├čig h├Ąlt das Android-System Ihren App-Prozess an, wenn es auf einen Speicherblock zugreift, den Sie einem Watchpoint zuweisen

Sie k├Ânnen diese Option deaktivieren, wenn Sie dieses Verhalten nicht w├╝nschen ÔÇô dadurch werden zus├Ątzliche Optionen angezeigt, mit denen Sie das Verhalten anpassen k├Ânnen, wenn das System mit Ihrem Watchpoint interagiert: Nachricht an Konsole protokollieren und [den Watchpoint] entfernen, wenn Sie darauf klicken.

Standardm├Ą├čig h├Ąlt das Android-System Ihren App-Prozess an, wenn es auf einen Speicherblock zugreift, den Sie einem ├ťberwachungspunkt zuweisen

Sie k├Ânnen diese Option deaktivieren, wenn Sie dieses Verhalten nicht w├╝nschen ÔÇô dadurch werden zus├Ątzliche Optionen angezeigt, mit denen Sie das Verhalten anpassen k├Ânnen, wenn das System mit Ihrem Watchpoint interagiert: und

Zugriffstyp: W├Ąhlen Sie aus, ob Ihre App Ihren Watchpoint ausl├Âsen soll, wenn sie versucht, in den Speicherblock zu lesen oder zu schreiben, den das System der Variablen zuweist

Um Ihren Watchpoint entweder bei einem Lese- oder Schreibvorgang auszul├Âsen, w├Ąhlen Sie Beliebig aus

Klicken Sie auf ÔÇ×FertigÔÇť

Um alle Ihre Watchpoints anzuzeigen und Watchpoint-Einstellungen zu konfigurieren, klicken Sie auf der linken Seite des Debug-Fensters auf Breakpoints anzeigen

Das Dialogfeld “Haltepunkte” wird angezeigt, wie in Abbildung 8 gezeigt

Abbildung 8

Das Dialogfeld “Haltepunkte” listet Ihre aktuellen ├ťberwachungspunkte auf und enth├Ąlt Verhaltenseinstellungen f├╝r jeden

Nachdem Sie Ihren ├ťberwachungspunkt hinzugef├╝gt haben, klicken Sie auf der linken Seite des Debug-Fensters auf Programm fortsetzen, um Ihren App-Prozess fortzusetzen

Wenn Ihre App versucht, auf einen Speicherblock zuzugreifen, f├╝r den Sie einen Watchpoint festgelegt haben, h├Ąlt das Android-System standardm├Ą├čig Ihren App-Prozess an und ein Watchpoint-Symbol wird neben der Codezeile angezeigt, die Ihre App zuletzt ausgef├╝hrt hat, wie in Abbildung 9 dargestellt.

Abbildung 9

Android Studio gibt die Codezeile an, die Ihre App unmittelbar vor dem Ausl├Âsen eines Watchpoints ausf├╝hrt

Anzeigeformat f├╝r Ressourcenwerte anzeigen und ├Ąndern

Im Debug-Modus k├Ânnen Sie Ressourcenwerte anzeigen und ein anderes Anzeigeformat f├╝r Variablen in Ihrem Java-Code ausw├Ąhlen

Gehen Sie bei angezeigter Registerkarte ÔÇ×VariablenÔÇť und ausgew├Ąhltem Rahmen wie folgt vor: Klicken Sie in der Variablenliste mit der rechten Maustaste irgendwo auf eine Ressourcenzeile, um die Dropdown-Liste anzuzeigen

W├Ąhlen Sie in der Dropdown-Liste Anzeigen als und das gew├╝nschte Format aus

Die verf├╝gbaren Formate h├Ąngen vom Datentyp der ausgew├Ąhlten Ressource ab

M├Âglicherweise sehen Sie eine oder mehrere der folgenden Optionen: Klasse: Zeigt die Klassendefinition an.

Zeigt die Klassendefinition an

toString: Zeichenkettenformat anzeigen.

Zeichenkettenformat anzeigen

Objekt: Zeigt die Objektdefinition (eine Instanz einer Klasse) an.

Zeigt die Objektdefinition (eine Instanz einer Klasse) an

Array: Anzeige in einem Array-Format.

Anzeige in einem Array-Format

Zeitstempel: Zeigt Datum und Uhrzeit wie folgt an: jjjj-mm-tt hh:mm:ss.

Zeigt Datum und Uhrzeit wie folgt an: jjjj-mm-tt hh:mm:ss

Auto: Android Studio w├Ąhlt das beste Format basierend auf dem Datentyp.

Android Studio w├Ąhlt das beste Format basierend auf dem Datentyp

Bin├Ąr: Zeigt einen Bin├Ąrwert mit Nullen und Einsen an.

Zeigt einen Bin├Ąrwert mit Nullen und Einsen an

See also  Best Choice autocad tiff einf├╝gen New

MeasureSpec: Der Wert, der vom ├╝bergeordneten Element an das ausgew├Ąhlte untergeordnete Element ├╝bergeben wird

Siehe MeasureSpec.

Der Wert, der vom Elternteil an das ausgew├Ąhlte Kind weitergegeben wird

See

Hex: Anzeige als Hexadezimalwert.

Anzeige als Hexadezimalwert

Primitiv: Anzeige als numerischer Wert unter Verwendung eines primitiven Datentyps.

Anzeige als numerischer Wert unter Verwendung eines primitiven Datentyps

Integer: Zeigt einen numerischen Wert vom Typ Integer an

Sie k├Ânnen wie folgt ein benutzerdefiniertes Format (Datentyp-Renderer) erstellen:

đÜĐâđ┤đ░ đ▓Đőđ▓đżđ┤đŞĐé Đüđżđżđ▒ĐëđÁđŻđŞđÁ Debug Print? VBA New

Video unten ansehen

Weitere hilfreiche Informationen im Thema anzeigen debug print

debug print Sie k├Ânnen die sch├Ânen Bilder im Thema sehen

 Update đÜĐâđ┤đ░ đ▓Đőđ▓đżđ┤đŞĐé Đüđżđżđ▒ĐëđÁđŻđŞđÁ Debug Print? VBA
đÜĐâđ┤đ░ đ▓Đőđ▓đżđ┤đŞĐé Đüđżđżđ▒ĐëđÁđŻđŞđÁ Debug Print? VBA Update New

DebugRust By Example New

Debug. All types which want to use std::fmt formatting traits require an implementation to be printable. Automatic implementations are only provided for types such as in the std library. All others must be manually implemented somehow.. The fmt::Debug trait makes this very straightforward.All types can derive (automatically create) the fmt::Debug implementation. . ÔÇŽ

+ Details hier sehen

Read more

Alle Typen, die std::fmt-Formatierungsmerkmale verwenden m├Âchten, ben├Âtigen eine Implementierung, um druckbar zu sein

Automatische Implementierungen werden nur f├╝r Typen wie in der std-Bibliothek bereitgestellt

Alle anderen m├╝ssen irgendwie manuell implementiert werden

Das Merkmal fmt::Debug macht dies sehr einfach

Alle Typen k├Ânnen die fmt::Debug-Implementierung ableiten (automatisch erstellen)

Dies gilt nicht f├╝r fmt::Display, das manuell implementiert werden muss

#![allow(unused)] fn main() { // Diese Struktur kann weder mit `fmt::Display` noch // mit `fmt ausgegeben werden ::Debug`

struct UnPrintable (i32); // Das `derive`-Attribut erstellt automatisch die // Implementierung, die erforderlich ist, um dieses `struct` mit `fmt::Debug` druckbar zu machen

#[derive(Debug)] struct DebugPrintable(i32); }

Alle std-Bibliothekstypen sind auch automatisch mit {:?} druckbar:

// Leite die `fmt::Debug`-Implementierung f├╝r `Structure` ab

`Structure` // ist eine Struktur, die ein einzelnes `i32` enth├Ąlt

#[ableiten(Debug)] struct Structure(i32); // F├╝ge eine `Structure` in die Struktur `Deep` ein

Machen Sie es auch druckbar //

#[derive(Debug)] struct Deep(Struktur); fn main() { // Drucken mit `{:?}` ist ├Ąhnlich wie mit `{}`

println!(“{:?} Monate in einem Jahr.”, 12); println!(“{1:?} {0:?} ist der Name von {Schauspieler:?}.”, “Slater”, “Christian”, actor=”Schauspieler”); // `Struktur` ist druckbar! println!(“Jetzt wird {:?} gedruckt!”, Structure(3)); // Das Problem mit `derive` ist, dass es keine Kontrolle dar├╝ber gibt, // wie die Ergebnisse aussehen

Was ist, wenn ich m├Âchte, dass hier nur eine ÔÇ×7ÔÇť angezeigt wird? println!(“Jetzt will {:?} drucken!”, Deep(Structure(7))); }

fmt::Debug macht dies also definitiv druckbar, opfert jedoch etwas Eleganz

Rust bietet auch “h├╝bsches Drucken” mit {:#?}.

#[derive(Debug)] struct Person<'a> { name: &’a str, age: u8 } fn main() { let name = “Peter “; letztes Alter = 27; let peter = Person { Name, Alter }; // Sch├Âner Druck println!(“{:#?}”, peter); }

Man kann fmt::Display manuell implementieren, um die Anzeige zu steuern.

13.1 – Debugging with Print Statements Update

Video unten ansehen

Neues Update zum Thema debug print

debug print Ähnliche Bilder im Thema

 New 13.1 - Debugging with Print Statements
13.1 – Debugging with Print Statements Update New

January 2022 Printable Calendar Update

Print a calendar for January 2022 quickly and easily. Just click print right from your browser. Doesn’t get easier than that.

+ ausf├╝hrliche Artikel hier sehen

Variables, MsgBox, Debug.Print Tutorial: Excel VBA Update

Video ansehen

Neues Update zum Thema debug print

debug print Ähnliche Bilder im Thema

 New Update Variables, MsgBox, Debug.Print Tutorial: Excel VBA
Variables, MsgBox, Debug.Print Tutorial: Excel VBA Update

Lua 5.1 Reference Manual Update New

lua_createtable [-0, +1, m] void lua_createtable (lua_State *L, int narr, int nrec); Creates a new empty table and pushes it onto the stack. The new table has space pre-allocated for narr array elements and nrec non-array elements. This pre-allocation is useful when you know exactly how many elements the table will have.

+ Details hier sehen

Read more

Lua 5.1 Referenzhandbuch

von Roberto Ierusalimschy, Luiz Henrique de Figueiredo und Waldemar Celes

Copyright ┬ę 2006-2012 Lua.org, PUC-Rio

Frei verf├╝gbar unter den Bedingungen der Lua-Lizenz

1 ÔÇô Einf├╝hrung

Lua ist eine Erweiterungsprogrammiersprache, die entwickelt wurde, um die allgemeine prozedurale Programmierung mit Datenbeschreibungsfunktionen zu unterst├╝tzen

Es bietet auch gute Unterst├╝tzung f├╝r objektorientierte Programmierung, funktionale Programmierung und datengesteuerte Programmierung

Lua soll als leistungsstarke, leichte Skriptsprache f├╝r jedes Programm verwendet werden, das eine ben├Âtigt

Lua ist als Bibliothek implementiert, die in sauberem C geschrieben ist (d

h

in der gemeinsamen Teilmenge von ANSI C und C++)

Als Erweiterungssprache hat Lua keine Vorstellung von einem ÔÇ×HauptprogrammÔÇť: Es funktioniert nur eingebettet in einen Host Client, genannt Einbettungsprogramm oder einfach Host

Dieses Host-Programm kann Funktionen aufrufen, um ein St├╝ck Lua-Code auszuf├╝hren, kann Lua-Variablen schreiben und lesen und kann C-Funktionen registrieren, die von Lua-Code aufgerufen werden sollen

Durch die Verwendung von C-Funktionen kann Lua erweitert werden, um eine Vielzahl unterschiedlicher Dom├Ąnen zu bew├Ąltigen, wodurch kundenspezifische Programmiersprachen mit einem gemeinsamen syntaktischen Rahmen erstellt werden

Die Lua-Distribution enth├Ąlt ein Beispiel-Hostprogramm namens lua , das die Lua-Bibliothek verwendet, um einen vollst├Ąndigen, eigenst├Ąndigen Lua-Interpreter bereitzustellen

Lua ist kostenlose Software und wird wie ├╝blich ohne Garantien bereitgestellt, wie in seiner Lizenz angegeben

Die in diesem Handbuch beschriebene Implementierung ist auf der offiziellen Website von Lua, www.lua.org, verf├╝gbar

Wie jedes andere Referenzhandbuch ist dieses Dokument stellenweise trocken

Eine Diskussion der Entscheidungen hinter dem Design von Lua finden Sie in den technischen Dokumenten, die auf der Website von Lua verf├╝gbar sind

Eine ausf├╝hrliche Einf├╝hrung in die Programmierung mit Lua finden Sie in Robertos Buch Programming in Lua (Second Edition)

2 ÔÇô The Language

Dieser Abschnitt beschreibt die Lexik, die Syntax und die Semantik von Lua

Mit anderen Worten, dieser Abschnitt beschreibt, welche Tokens g├╝ltig sind, wie sie kombiniert werden k├Ânnen und was ihre Kombinationen bedeuten [a] bedeutet ein optionales a

Nichtterminale werden als Nichtterminal angezeigt, Schl├╝sselw├Ârter werden als kword angezeigt und andere Terminalsymbole werden als `=┬┤ angezeigt

Die vollst├Ąndige Syntax von Lua finden Sie in ┬ž8 am Ende dieses Handbuchs.

Namen (auch Bezeichner genannt) in Lua k├Ânnen eine beliebige Folge von Buchstaben, Ziffern und Unterstrichen sein, die nicht mit einer Ziffer beginnen

Dies stimmt mit der Definition von Namen in den meisten Sprachen ├╝berein

(Die Definition von Buchstaben h├Ąngt von der aktuellen L├Ąndereinstellung ab: jedes Zeichen, das von der aktuellen L├Ąndereinstellung als alphabetisch angesehen wird, kann in einem Bezeichner verwendet werden.) Bezeichner werden verwendet, um Variablen und Tabellenfelder zu benennen

Die folgenden Schl├╝sselw├Ârter sind reserviert und k├Ânnen nicht als Namen verwendet werden:

and break do elseif end false for function if in local nil not or repeat return then true until while

Lua unterscheidet zwischen Gro├č- und Kleinschreibung: und ist ein reserviertes Wort, aber And und AND sind zwei verschiedene, g├╝ltige Namen

Als Konvention sind Namen, die mit einem Unterstrich gefolgt von Gro├čbuchstaben beginnen (z

B

_VERSION ), f├╝r interne globale Variablen reserviert, die von Lua verwendet werden

Die folgenden Zeichenfolgen bezeichnen andere Token:

+ – * / % ^ # == ~= <= >= < > = ( ) { } [ ] ; : ,

.

Literale Zeichenfolgen k├Ânnen durch passende einfache oder doppelte Anf├╝hrungszeichen getrennt werden und k├Ânnen die folgenden C-├Ąhnlichen Escape-Sequenzen enthalten: ‘ \a ‘ (Glocke), ‘ \b ‘ (R├╝cktaste), ‘ \f ‘ ( Formularvorschub), ‘

‘ (Zeilenumbruch), ‘ \r ‘ (Wagenr├╝cklauf), ‘ \t ‘ (horizontaler Tabulator), ‘ \v ‘ (vertikaler Tabulator), ‘ \\ ‘ (Backslash), ‘ \” ‘ (Anf├╝hrungszeichen [doppeltes Anf├╝hrungszeichen ]) und ‘ \’ ‘ (Apostroph [einfaches Anf├╝hrungszeichen])

Dar├╝ber hinaus f├╝hrt ein Backslash gefolgt von einem echten Zeilenumbruch zu einem Zeilenumbruch in der Zeichenfolge \ddd , wobei ddd eine Folge von bis zu drei Dezimalziffern ist

(Beachten Sie, dass wenn auf ein numerisches Escape eine Ziffer folgen soll, muss es mit genau drei Ziffern ausgedr├╝ckt werden.) Strings in Lua k├Ânnen jeden 8-Bit-Wert enthalten, einschlie├člich eingebetteter Nullen, die als ‘ \0 ‘ angegeben werden k├Ânnen

Wir definieren eine ├Âffnende lange Klammer der Ebene n als ├Âffnende eckige Klammer, gefolgt von n Gleichheitszeichen, gefolgt von einer weiteren ├Âffnenden eckigen Klammer

Eine ├Âffnende lange Klammer der Ebene 0 wird also geschrieben als [[ , eine ├Âffnende lange Klammer der Ebene 1 wird geschrieben als [ =[ usw

Eine schlie├čende lange Klammer wird ├Ąhnlich definiert, zum Beispiel wird eine schlie├čende lange Klammer der Ebene 4 geschrieben als ]====] Eine lange Zeichenkette beginnt mit einer ├Âffnenden langen Klammer einer beliebigen Ebene a nd endet mit der ersten schlie├čenden langen Klammer derselben Ebene

Literale in dieser Klammerform k├Ânnen ├╝ber mehrere Zeilen laufen, interpretieren keine Escape-Sequenzen und ignorieren lange Klammern anderer Ebenen

Sie k├Ânnen alles au├čer einer schlie├čenden Klammer der richtigen Ebene enthalten

Wenn der ├Âffnenden langen Klammer unmittelbar ein Zeilenumbruch folgt, wird der Zeilenumbruch der Einfachheit halber nicht in die Zeichenfolge eingeschlossen

Beispielsweise bezeichnen in einem System, das ASCII verwendet (in dem ‘ a ‘ als 97 codiert ist, Newline als 10 codiert ist, und ‘ 1 ‘ als 49 codiert ist), die f├╝nf w├Ârtlichen Zeichenfolgen unten dieselbe Zeichenfolge:

a = ‘alo

123″‘ a = “alo

123\”” a = ‘\97lo\10\04923″‘ a = [[alo 123″]] a = [==[ alo 123″]==]

ein optionaler Dezimalexponent

Lua akzeptiert auch ganzzahlige Hexadezimalkonstanten, indem Sie ihnen 0x voranstellen

Beispiele f├╝r g├╝ltige numerische Konstanten sind: 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56

Ein Kommentar beginnt mit einem doppelten Bindestrich ( — ) irgendwo au├čerhalb Wenn der Text unmittelbar nach — kein ├Âffnender langer ist Klammer, der Kommentar ist ein kurzer Kommentar, der bis zum Ende der Zeile l├Ąuft

Lange Kommentare werden h├Ąufig verwendet, um Code vor├╝bergehend zu deaktivieren.

Lua ist eine dynamisch typisierte Sprache

Das bedeutet, dass Variablen keine Typen haben, sondern nur Werte Es gibt keine Typdefinitionen in der Sprache

Alle Werte tragen ihren eigenen Typ

Alle Werte in Lua sind erstklassige Werte

Das bedeutet, dass alle Werte in Variablen gespeichert und als Argumente an andere Funktionen ├╝bergeben werden k├Ânnen , und als Ergebnisse zur├╝ckgegeben.

Es gibt acht grundlegende Typen in Lua: nil, boolean, number, string, function, userdata, thread und table.Nil ist der Typ von va lue nil, dessen Haupteigenschaft darin besteht, sich von jedem anderen Wert zu unterscheiden; es stellt normalerweise das Fehlen eines n├╝tzlichen Werts dar

Boolean ist der Typ der Werte false und true

Sowohl nil als auch false machen eine Bedingung falsch; jeder andere Wert macht es wahr

Zahl steht f├╝r reelle Zahlen (Gleitkommazahlen mit doppelter Genauigkeit)

(Es ist einfach, Lua-Interpreter zu bauen, die andere interne Darstellungen f├╝r Zahlen verwenden, wie z

B

Gleitkommazahlen mit einfacher Genauigkeit oder lange Ganzzahlen; siehe Datei luaconf.h. ) String repr├Ąsentiert Arrays von Zeichen

Lua ist 8-Bit-sauber: Strings k├Ânnen jedes 8-Bit-Zeichen enthalten, einschlie├člich eingebetteter Nullen (‘\0’) (siehe ┬ž2.1)

Lua kann in Lua geschriebene Funktionen und in C geschriebene Funktionen aufrufen (und manipulieren) (siehe ┬ž2.5.8).

Der Typ userdata wird bereitgestellt, damit beliebige C-Daten in Lua-Variablen gespeichert werden k├Ânnen

Dieser Typ entspricht einem Rohspeicherblock und hat keine vordefinierten Operationen in Lua, au├čer Zuweisung und Identit├Ątstest

Durch die Verwendung von Metatabellen kann der Programmierer jedoch Operationen f├╝r Benutzerdatenwerte definieren (siehe ┬ž2.8)

Benutzerdatenwerte k├Ânnen in Lua nicht erstellt oder ge├Ąndert werden, sondern nur ├╝ber die C-API

Dies garantiert die Integrit├Ąt der Daten, die dem Host-Programm geh├Âren

Der Typ Thread stellt unabh├Ąngige Ausf├╝hrungs-Threads dar und wird verwendet, um Coroutinen zu implementieren (siehe ┬ž2.11)

Verwechseln Sie Lua-Threads nicht mit Betriebssystem-Threads

Lua unterst├╝tzt Coroutinen auf allen Systemen, auch auf solchen, die keine Threads unterst├╝tzen

Die Typtabelle implementiert assoziative Arrays, dh Arrays, die nicht nur mit Zahlen, sondern mit beliebigen Werten (au├čer Null) indiziert werden k├Ânnen

Tabellen k├Ânnen heterogen sein; das hei├čt, sie k├Ânnen Werte aller Art enthalten (au├čer Null)

Tabellen sind der einzige Datenstrukturierungsmechanismus in Lua; Sie k├Ânnen verwendet werden, um gew├Âhnliche Arrays, Symboltabellen, Mengen, Datens├Ątze, Diagramme, B├Ąume usw

darzustellen

Um Datens├Ątze darzustellen, verwendet Lua den Feldnamen als Index

Die Sprache unterst├╝tzt diese Darstellung, indem sie a.name als syntaktischen Zucker f├╝r a[“name”] bereitstellt

Es gibt mehrere praktische M├Âglichkeiten, Tabellen in Lua zu erstellen (siehe ┬ž2.5.7)

Wie Indizes kann der Wert eines Tabellenfeldes jeden Typs haben (au├čer Null)

Insbesondere weil Funktionen erstklassige Werte sind, k├Ânnen Tabellenfelder Funktionen enthalten

Tabellen k├Ânnen also auch Methoden tragen (siehe ┬ž2.5.9)

Tabellen, Funktionen, Threads und (vollst├Ąndige) Benutzerdatenwerte sind Objekte: Variablen enthalten diese Werte nicht wirklich, sondern nur Verweise darauf

Zuweisungen, Parameter├╝bergaben und Funktionsr├╝ckgaben sind immer manipulierte Verweise auf solche Werte; Diese Operationen implizieren keine Art von Kopie

Der Typ der Bibliotheksfunktion gibt eine Zeichenfolge zur├╝ck, die den Typ eines bestimmten Werts beschreibt

Lua bietet zur Laufzeit eine automatische Konvertierung zwischen Zeichenfolgen- und Zahlenwerten

Jede arithmetische Operation, die auf eine Zeichenfolge angewendet wird, versucht, diese Zeichenfolge gem├Ą├č den ├╝blichen Konvertierungsregeln in eine Zahl umzuwandeln

Wenn umgekehrt eine Zahl verwendet wird, wo eine Zeichenkette erwartet wird, wird die Zahl in einem angemessenen Format in eine Zeichenkette umgewandelt

Verwenden Sie f├╝r vollst├Ąndige Kontrolle dar├╝ber, wie Zahlen in Strings konvertiert werden, die Formatfunktion aus der Stringbibliothek (siehe string.format )

Variablen sind Orte, an denen Werte gespeichert werden

Es gibt drei Arten von Variablen in Lua: globale Variablen, lokale Variablen und Tabellenfelder.

Ein einzelner Name kann eine globale Variable oder eine lokale Variable bezeichnen (oder den formalen Parameter einer Funktion, der eine bestimmte Art von lokaler Variable ist):

var ::= Name

Name bezeichnet Bezeichner, wie in ┬ž2.1 definiert

Jede Variable wird als global angenommen, es sei denn, sie wird ausdr├╝cklich als lokal deklariert (siehe ┬ž2.4.7)

Lokale Variablen haben einen lexikalischen Geltungsbereich: Auf lokale Variablen kann durch Funktionen, die in ihrem Geltungsbereich definiert sind, frei zugegriffen werden (siehe ┬ž2.6)

Vor der ersten Zuweisung an eine Variable ist ihr Wert null

Eckige Klammern werden verwendet, um eine Tabelle zu indizieren:

var ::= Pr├Ąfixexp `[┬┤ exp `]┬┤

Die Bedeutung von Zugriffen auf globale Variablen und Tabellenfelder kann ├╝ber Metatables ver├Ąndert werden

Ein Zugriff auf eine indizierte Variable t[i] entspricht einem Aufruf gettable_event(t,i)

(Siehe ┬ž2.8 f├╝r eine vollst├Ąndige Beschreibung der Funktion gettable_event

Diese Funktion ist in Lua nicht definiert oder aufrufbar

Wir verwenden sie hier nur zu Erl├Ąuterungszwecken.) Die Syntax var.Name ist nur syntaktischer Zucker f├╝r var[“Name”] :

var ::= Pr├Ąfixexp `.┬┤ Name

Alle globalen Variablen leben als Felder in gew├Âhnlichen Lua-Tabellen, Umgebungstabellen oder einfach Umgebungen genannt (siehe ┬ž2.9)

Jede Funktion hat ihren eigenen Verweis auf eine Umgebung, sodass alle globalen Variablen in dieser Funktion auf diese Umgebungstabelle verweisen

Wenn eine Funktion erstellt wird, erbt sie die Umgebung von der Funktion, die sie erstellt hat

Um die Umgebungstabelle einer Lua-Funktion abzurufen, rufen Sie getfenv auf

Um es zu ersetzen, rufen Sie setfenv auf

(Sie k├Ânnen die Umgebung von C-Funktionen nur ├╝ber die Debug-Bibliothek manipulieren; (siehe ┬ž5.9).)

Ein Zugriff auf eine globale Variable x ist ├Ąquivalent zu _env.x , was wiederum ├Ąquivalent zu ist

gettable_event(_env, “x”)

wobei _env die Umgebung der laufenden Funktion ist

(Siehe ┬ž2.8 f├╝r eine vollst├Ąndige Beschreibung der Funktion gettable_event

Diese Funktion ist in Lua nicht definiert oder aufrufbar

Ebenso ist die Variable _env in Lua nicht definiert

Wir verwenden sie hier nur zu Erl├Ąuterungszwecken.) Lua unterst├╝tzt einen fast konventionellen Satz von Anweisungen, ├Ąhnlich denen in Pascal oder C

Dieser Satz umfasst Zuweisungen, Kontrollstrukturen, Funktionsaufrufe und Variablendeklarationen

Die Ausf├╝hrungseinheit von Lua wird Chunk genannt

Ein Chunk ist einfach eine Folge von Anweisungen, die nacheinander ausgef├╝hrt werden

Jeder Anweisung kann optional ein Semikolon folgen:

St├╝ck ::= {stat [`;┬┤]}

Es gibt keine leeren Anweisungen und daher ‘ ;; ‘ ist nicht zul├Ąssig

Lua behandelt einen Chunk als K├Ârper einer anonymen Funktion mit einer variablen Anzahl von Argumenten (siehe ┬ž2.5.9)

Als solche k├Ânnen Chunks lokale Variablen definieren, Argumente empfangen und Werte zur├╝ckgeben

Ein Chunk kann in einer Datei oder in einem String innerhalb des Host-Programms gespeichert werden

Um einen Chunk auszuf├╝hren, kompiliert Lua den Chunk zun├Ąchst in Anweisungen f├╝r eine virtuelle Maschine und f├╝hrt dann den kompilierten Code mit einem Interpreter f├╝r die virtuelle Maschine aus

Chunks k├Ânnen auch in bin├Ąrer Form vorkompiliert werden; siehe Programm luac f├╝r Details

Programme in Quell- und kompilierter Form sind austauschbar; Lua erkennt automatisch den Dateityp und handelt entsprechend

Ein Block ist eine Liste von Anweisungen; syntaktisch ist ein block dasselbe wie ein chunk:

Block ::= St├╝ck

Ein Block kann explizit begrenzt werden, um eine einzelne Anweisung zu erzeugen:

stat ::= Blockende ausf├╝hren

Explizite Bl├Âcke sind n├╝tzlich, um den Umfang von Variablendeklarationen zu steuern

Explizite Bl├Âcke werden manchmal auch verwendet, um eine return- oder break-Anweisung in die Mitte eines anderen Blocks einzuf├╝gen (siehe ┬ž2.4.4)

Lua erlaubt Mehrfachzuweisungen

Daher definiert die Syntax f├╝r Zuweisungen auf der linken Seite eine Liste von Variablen und auf der rechten Seite eine Liste von Ausdr├╝cken

Die Elemente in beiden Listen werden durch Kommas getrennt:

stat ::= varlist `=┬┤ explist varlist ::= var {`,┬┤ var} explist ::= exp {`,┬┤ exp}

Ausdr├╝cke werden in ┬ž2.5 behandelt

Vor der Zuweisung wird die Werteliste an die L├Ąnge der Variablenliste angepasst

Wenn mehr Werte als ben├Âtigt vorhanden sind, werden die ├╝bersch├╝ssigen Werte verworfen

Wenn es weniger Werte als n├Âtig gibt, wird die Liste um so viele Nullen wie n├Âtig erweitert

Wenn die Liste der Ausdr├╝cke mit einem Funktionsaufruf endet, werden alle von diesem Aufruf zur├╝ckgegebenen Werte vor der Anpassung in die Werteliste eingetragen (au├čer wenn der Aufruf in Klammern eingeschlossen ist; siehe ┬ž2.5)

Die Zuweisungsanweisung wird zuerst ausgewertet alle seine Ausdr├╝cke und erst dann werden die Zuweisungen durchgef├╝hrt

Also der Code

i = 3 i, a[i] = i+1, 20

setzt a[3] auf 20, ohne a[4] zu beeinflussen, da das i in a[i] ausgewertet wird (auf 3), bevor ihm 4 zugewiesen wird

Ebenso die Linie

x,y = y,x

tauscht die Werte von x und y aus, und

x, y, z = y, z, x

permutiert zyklisch die Werte von x , y , und z.

Die Bedeutung von Zuweisungen an globale Variablen und Tabellenfelder kann ├╝ber Metatables ge├Ąndert werden

Eine Zuweisung an eine indizierte Variable t[i] = val ist ├Ąquivalent zu settable_event(t,i,val)

(Siehe ┬ž2.8 f├╝r eine vollst├Ąndige Beschreibung der Funktion settable_event

Diese Funktion ist in Lua nicht definiert oder aufrufbar

Wir verwenden sie hier nur zu Erl├Ąuterungszwecken.)

Eine Zuweisung an eine globale Variable x = val entspricht der Zuweisung _env.x = val , die wiederum ├Ąquivalent zu ist

settable_event(_env, “x”, val)

wobei _env die Umgebung der laufenden Funktion ist

(Die Variable _env ist in Lua nicht definiert

Wir verwenden sie hier nur zu Erkl├Ąrungszwecken.) Die Kontrollstrukturen if, while und repeat haben die ├╝bliche Bedeutung und die vertraute Syntax:

stat ::= while exp do block end stat ::= repeat block until exp stat ::= if exp then block {elseif exp then block} [else block] end

Lua hat auch eine for-Anweisung in zwei Varianten (siehe ┬ž2.4.5)

Der Bedingungsausdruck einer Kontrollstruktur kann einen beliebigen Wert zur├╝ckgeben

Sowohl false als auch nil werden als false angesehen

Alle von nil und false verschiedenen Werte gelten als wahr (insbesondere die Zahl 0 und der leere String sind ebenfalls wahr)

In der repeatÔÇôuntil-Schleife endet der innere Block nicht beim until-Schl├╝sselwort, sondern erst danach die Bedingung

Die Bedingung kann sich also auf lokale Variablen beziehen, die innerhalb des Schleifenblocks deklariert sind

Die return-Anweisung wird verwendet, um Werte von einer Funktion oder einem Chunk (der nur eine Funktion ist) zur├╝ckzugeben

Funktionen und Chunks k├Ânnen mehr als einen Wert zur├╝ckgeben, und so lautet die Syntax f├╝r die return-Anweisung

stat ::= return [explist]

Die break-Anweisung wird verwendet, um die Ausf├╝hrung einer while-, repeat- oder for-Schleife zu beenden und zur n├Ąchsten Anweisung nach der Schleife zu springen:

stat ::= Pause

Ein break beendet die innerste umschlie├čende Schleife

Die return- und break-Anweisungen k├Ânnen nur als letzte Anweisung eines Blocks geschrieben werden

Wenn es wirklich notwendig ist, in der Mitte eines Blocks zur├╝ckzukehren oder umzubrechen, kann ein expliziter innerer Block verwendet werden, wie in den Redewendungen do return end und do break end , weil jetzt return und break die letzten Anweisungen in ihrem (inner ) Bl├Âcke.

Die for-Anweisung hat zwei Formen: eine numerische und eine generische.

Die numerische for-Schleife wiederholt einen Codeblock, w├Ąhrend eine Kontrollvariable eine arithmetische Folge durchl├Ąuft

Es hat die folgende Syntax:

stat ::= for Name `=┬┤ exp `,┬┤ exp [`,┬┤ exp] do block end

Der Block wird f├╝r name beginnend mit dem Wert des ersten Ausdrucks wiederholt, bis er den zweiten Ausdruck in Schritten des dritten Ausdrucks passiert

Genauer gesagt, eine for-Anweisung wie

f├╝r v = e1, e2, e3 do block end

entspricht dem Code:

do local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3) if not (var and limit and step) then error() end while (step > 0 and var <= limit) or (step <= 0 und var >= limit) do local v = var block var = var + step end end

Beachte das Folgende:

Alle drei Steuerausdr├╝cke werden nur einmal ausgewertet, bevor die Schleife beginnt

Sie m├╝ssen alle zu Zahlen f├╝hren

var , limit und step sind unsichtbare Variablen

Die hier gezeigten Namen dienen nur der Erl├Ąuterung

, , und sind unsichtbare Variablen

Die hier gezeigten Namen dienen nur der Erl├Ąuterung

Wenn der dritte Ausdruck (der Schritt) fehlt, wird ein Schritt von 1 verwendet.

Sie k├Ânnen break verwenden, um eine for-Schleife zu verlassen.

, um eine Schleife zu verlassen

Die Schleifenvariable v ist lokal f├╝r die Schleife; Sie k├Ânnen seinen Wert nicht verwenden, nachdem das for endet oder unterbrochen ist

Wenn Sie diesen Wert ben├Âtigen, weisen Sie ihn einer anderen Variablen zu, bevor Sie die Schleife unterbrechen oder verlassen

Die generische for-Anweisung arbeitet mit Funktionen, die als Iteratoren bezeichnet werden

Bei jeder Iteration wird die Iteratorfunktion aufgerufen, um einen neuen Wert zu erzeugen, und stoppt, wenn dieser neue Wert Null ist

Die generische for-Schleife hat die folgende Syntax:

stat ::= for namelist in explist do block end namelist ::= Name {`,┬┤ Name}

Eine for-Anweisung wie

f├╝r var_1, ┬Ě┬Ě┬Ě, var_n in explist do block end

entspricht dem Code:

do local f, s, var = explist while true do local var_1, var_n = f(s, var) var = var_1 if var == nil then break end block end end

Beachte das Folgende:

Explist wird nur einmal ausgewertet

Seine Ergebnisse sind eine Iteratorfunktion, ein Zustand und ein Anfangswert f├╝r die erste Iteratorvariable.

wird nur einmal ausgewertet

Seine Ergebnisse sind eine Iteratorfunktion, ein Zustand und ein Anfangswert f├╝r die erste Iteratorvariable

f , s und var sind unsichtbare Variablen

Die Namen dienen hier nur der Erl├Ąuterung.

, , und sind unsichtbare Variablen

Die Namen dienen hier nur der Erl├Ąuterung

Sie k├Ânnen break verwenden, um eine for-Schleife zu verlassen.

um eine Schleife zu verlassen

Die Schleifenvariablen var_i sind lokal f├╝r die Schleife; Sie k├Ânnen ihre Werte nach dem Ende von for nicht verwenden

Wenn Sie diese Werte ben├Âtigen, weisen Sie sie anderen Variablen zu, bevor Sie die Schleife unterbrechen oder verlassen

Um m├Âgliche Nebeneffekte zuzulassen, k├Ânnen Funktionsaufrufe als Anweisungen ausgef├╝hrt werden:

stat ::= Funktionsaufruf

In diesem Fall werden alle zur├╝ckgegebenen Werte verworfen

Funktionsaufrufe werden in ┬ž2.5.8 erkl├Ąrt

Lokale Variablen k├Ânnen ├╝berall innerhalb eines Blocks deklariert werden

Die Deklaration kann eine anf├Ąngliche Zuweisung enthalten:

stat ::= lokale Namensliste [`=┬┤ explist]

Falls vorhanden, hat eine anf├Ąngliche Zuweisung dieselbe Semantik wie eine Mehrfachzuweisung (siehe ┬ž2.4.3)

Andernfalls werden alle Variablen mit null initialisiert

Ein Chunk ist auch ein Block (siehe ┬ž2.4.1), und daher k├Ânnen lokale Variablen in einem Chunk au├čerhalb eines expliziten Blocks deklariert werden

Der G├╝ltigkeitsbereich solcher lokaler Variablen erstreckt sich bis zum Ende des Chunks

Die Sichtbarkeitsregeln f├╝r lokale Variablen werden in ┬ž2.6 erkl├Ąrt

Die grundlegenden Ausdr├╝cke in Lua sind die folgenden:

exp ::= Pr├Ąfixexp exp ::= nil | falsch | true exp ::= Nummer exp ::= String exp ::= function exp ::= tableconstructor exp ::= `…┬┤ exp ::= exp binop exp exp ::= unop exp prefixexp ::= var | Funktionsaufruf | `(┬┤ exp `)┬┤

Zahlen und Literal-Strings werden in ┬ž2.1 erkl├Ąrt; Variablen werden in ┬ž2.3 erkl├Ąrt; Funktionsdefinitionen werden in ┬ž2.5.9 erl├Ąutert; Funktionsaufrufe werden in ┬ž2.5.8 erkl├Ąrt; Tabellenkonstruktoren werden in ┬ž2.5.7 erkl├Ąrt

Vararg-Ausdr├╝cke, gekennzeichnet durch drei Punkte (‘. .

‘), k├Ânnen nur direkt innerhalb einer vararg-Funktion verwendet werden; sie werden in ┬ž2.5.9 erl├Ąutert

Bin├Ąre Operatoren umfassen arithmetische Operatoren (siehe ┬ž2.5.1), relationale Operatoren (siehe ┬ž2.5.2), logische Operatoren (siehe ┬ž2.5.3) und den Verkettungsoperator (siehe ┬ž 2.5.4)

Un├Ąre Operatoren umfassen das un├Ąre Minus (siehe ┬ž2.5.1), das un├Ąre Not (siehe ┬ž2.5.3) und den un├Ąren L├Ąngenoperator (siehe ┬ž2.5.5)

Sowohl Funktionsaufrufe als auch Vararg-Ausdr├╝cke k├Ânnen zu mehreren Werten f├╝hren

Wenn ein Ausdruck als Anweisung verwendet wird (nur m├Âglich f├╝r Funktionsaufrufe (siehe ┬ž2.4.6)), dann wird seine R├╝ckgabeliste auf null Elemente angepasst, wodurch alle zur├╝ckgegebenen Werte verworfen werden

Wenn ein Ausdruck als letztes (oder einziges) Element einer Liste von Ausdr├╝cken verwendet wird, wird keine Anpassung vorgenommen (es sei denn, der Aufruf ist in Klammern eingeschlossen)

In allen anderen Kontexten passt Lua die Ergebnisliste auf ein Element an und verwirft alle Werte au├čer dem ersten

Hier einige Beispiele:

f() — auf 0 angepasst ergibt g(f(), x) — f() wird auf 1 angepasst Ergebnis g(x, f()) — g erh├Ąlt x plus alle Ergebnisse von f() a,b ,c = f(), x — f() wird auf 1 Ergebnis angepasst (c wird null) a,b =. .

— a erh├Ąlt den ersten vararg-Parameter, b erh├Ąlt — den zweiten (sowohl a als auch b kann Null werden, wenn es — keinen entsprechenden Vararg-Parameter gibt) a,b,c = x, f() — f() wird auf 2 Ergebnisse angepasst a,b,c = f() — f() wird angepasst bis 3 Ergebnisse return f() — gibt alle Ergebnisse von f() zur├╝ck return. .

— gibt alle empfangenen Vararg-Parameter zur├╝ck return x,y,f() — gibt x, y und alle Ergebnisse von f() zur├╝ck { f()} — erstellt eine Liste mit allen Ergebnissen von f() {…} — erstellt eine Liste mit allen Vararg-Parametern {f(), nil} — f() wird auf 1 Ergebnis eingestellt

Jeder in Klammern eingeschlossene Ausdruck ergibt immer nur einen Wert

Somit ist (f(x,y,z)) immer ein einziger Wert, auch wenn f mehrere Werte liefert

(Der Wert von (f(x,y,z)) ist der erste Wert, der von f zur├╝ckgegeben wird, oder nil, wenn f keine Werte zur├╝ckgibt.)

Lua unterst├╝tzt die ├╝blichen arithmetischen Operatoren: das bin├Ąre + (Addition), – (Subtraktion), * (Multiplikation), / (Division), % (Modulo) und ^ (Potenzierung); und un├Ąr – (Negation)

Wenn die Operanden Zahlen oder Zeichenketten sind, die in Zahlen umgewandelt werden k├Ânnen (siehe ┬ž2.2.1), dann haben alle Operationen die ├╝bliche Bedeutung

Exponentiation funktioniert f├╝r jeden Exponenten

Zum Beispiel berechnet x^(-0.5) die Inverse der Quadratwurzel von x

Modulo ist definiert als

a % b == a – math.floor(a/b)*b

Das hei├čt, es ist der Rest einer Division, die den Quotienten gegen minus unendlich rundet

Die Vergleichsoperatoren in Lua sind

== ~= < > <= >=

Diese Operatoren ergeben immer false oder true

Gleichheit ( == ) vergleicht zuerst den Typ seiner Operanden

Wenn die Typen unterschiedlich sind, ist das Ergebnis falsch

Andernfalls werden die Werte der Operanden verglichen

Zahlen und Zeichenketten werden auf die ├╝bliche Weise verglichen

Objekte (Tabellen, Benutzerdaten, Threads und Funktionen) werden durch Bezugnahme verglichen: Zwei Objekte werden nur dann als gleich angesehen, wenn sie dasselbe Objekt sind

Jedes Mal, wenn Sie ein neues Objekt erstellen (eine Tabelle, Benutzerdaten, ein Thread oder eine Funktion), unterscheidet sich dieses neue Objekt von allen zuvor vorhandenen Objekten

Sie k├Ânnen die Art und Weise ├Ąndern, wie Lua Tabellen und Benutzerdaten vergleicht, indem Sie die Metamethode ÔÇ×eqÔÇť siehe ┬ž2.8)

Die Konvertierungsregeln von ┬ž2.2.1 gelten nicht f├╝r Gleichheitsvergleiche

Daher wird “0”==0 als falsch ausgewertet, und t[0] und t[“0”] bezeichnen unterschiedliche Eintr├Ąge in einer Tabelle

Der Operator ~= ist genau die Negation der Gleichheit ( == )

Die Reihenfolge Operatoren arbeiten wie folgt

Wenn beide Argumente Zahlen sind, werden sie als solche verglichen

Andernfalls, wenn beide Argumente Zeichenfolgen sind, werden ihre Werte gem├Ą├č dem aktuellen Gebietsschema verglichen

Andernfalls versucht Lua, die “lt”- oder die “le”-Metamethode aufzurufen (siehe ┬ž2.8)

Ein Vergleich a > b wird ├╝bersetzt in b < a und a >= b wird ├╝bersetzt in b <= a.

Die logischen Operatoren in Lua sind and, or und not

Wie die Kontrollstrukturen (siehe ┬ž2.4.4) betrachten alle logischen Operatoren sowohl falsch als auch nil als falsch und alles andere als wahr

Der Negationsoperator gibt nicht immer falsch oder wahr zur├╝ck

Der Konjunktionsoperator und gibt sein erstes Argument zur├╝ck, wenn dieser Wert falsch oder nil ist; andernfalls und gibt sein zweites Argument zur├╝ck

Der Disjunktionsoperator oder gibt sein erstes Argument zur├╝ck, wenn dieser Wert sich von nil und false unterscheidet; andernfalls oder gibt sein zweites Argument zur├╝ck

Sowohl als auch als auch oder verwenden Sie eine abgek├╝rzte Auswertung; dh der zweite Operand wird nur bei Bedarf ausgewertet

Hier sind einige Beispiele:

10 oder 20 –> 10 10 oder error() –> 10 nil oder “a” –> “a” nil und 10 –> nil false und error() –> false false und nil –> false false oder nil –> nil 10 und 20 –> 20

(In diesem Handbuch gibt –> das Ergebnis des vorhergehenden Ausdrucks an.)

Der Zeichenfolgenverkettungsoperator in Lua wird durch zwei Punkte (‘.

‘) gekennzeichnet

Wenn beide Operanden Zeichenfolgen oder Zahlen sind, werden sie gem├Ą├č den in ┬ž2.2.1 genannten Regeln in Zeichenfolgen konvertiert

Andernfalls wird die “concat”-Metamethode aufgerufen (siehe ┬ž2.8)

Der L├Ąngenoperator wird durch den un├Ąren Operator # bezeichnet

Die L├Ąnge einer Zeichenfolge ist ihre Anzahl von Bytes (dh die ├╝bliche Bedeutung der Zeichenfolgenl├Ąnge, wenn jedes Zeichen ein Byte ist)

Die L├Ąnge einer Tabelle t ist als ein beliebiger ganzzahliger Index n definiert, so dass t[n] ist nicht nil und t[n+1] ist nil; au├čerdem kann n null sein, wenn t[1] null ist

Bei einem regul├Ąren Array mit Nicht-Null-Werten von 1 bis zu einem bestimmten n ist seine L├Ąnge genau das n , der Index seines letzten Werts

Wenn das Array “L├Âcher” hat (d

h

Nullwerte zwischen anderen Nicht-Null-Werten), dann kann #t jeder der Indizes sein, der direkt vor einem Null-Wert steht (d

h

es kann jeden solchen Null-Wert wie z Ende des Arrays)

oder und < > <= >= ~= ==.

+ – * / % not # – (un├Ąr) ^

Wie ├╝blich k├Ânnen Sie Klammern verwenden, um die Priorit├Ąten eines Ausdrucks zu ├Ąndern

Die Operatoren Verkettung (‘.

‘) und Potenzierung (‘ ^ ‘) sind rechtsassoziativ

Alle anderen bin├Ąren Operatoren bleiben assoziativ

Tabellenkonstruktoren sind Ausdr├╝cke, die Tabellen erstellen

Jedes Mal, wenn ein Konstruktor ausgewertet wird, wird eine neue Tabelle erstellt

Ein Konstruktor kann verwendet werden, um eine leere Tabelle zu erstellen oder um eine Tabelle zu erstellen und einige ihrer Felder zu initialisieren

Die allgemeine Syntax f├╝r Konstruktoren ist

Tabellenkonstruktor ::= `{┬┤ [fieldlist] `}┬┤ fieldlist ::= field {fieldsep field} [fieldsep] field ::= `[┬┤ exp `]┬┤ `=┬┤ exp | name `=┬┤ exp | exp fieldsep ::= `,┬┤ | `;┬┤

Jedes Feld der Form [exp1] = exp2 f├╝gt der neuen Tabelle einen Eintrag mit dem Schl├╝ssel exp1 und dem Wert exp2 hinzu

Ein Feld der Form name = exp entspricht [“name”] = exp

Schlie├člich sind Felder der Form exp ├Ąquivalent zu [i] = exp , wobei i aufeinanderfolgende numerische Ganzzahlen sind, beginnend mit 1

Felder in den anderen Formaten haben keinen Einfluss auf diese Z├Ąhlung

Zum Beispiel,

a = {[f(1)] = g; “x”, “y”; x = 1, f(x), [30] = 23; 45}

ist ├Ąquivalent zu

do local t = {} t[f(1)] = gt[1] = “x” — 1

Ausdruck t[2] = “y” — 2

Ausdruck tx = 1 — t[“x”] = 1 t[3] = f(x) — 3

Ausdruck t[30] = 23 t[4] = 45 — 4

Ausdruck a = t end

Wenn das letzte Feld in der Liste die Form exp hat und der Ausdruck ein Funktionsaufruf oder ein vararg-Ausdruck ist, dann werden alle von diesem Ausdruck zur├╝ckgegebenen Werte nacheinander in die Liste eingetragen (siehe ┬ž2.5.8)

Um dies zu vermeiden, schlie├čen Sie den Funktionsaufruf oder den vararg-Ausdruck in Klammern ein (siehe Abschnitt 2.5)

Die Feldliste kann ein optionales nachgestelltes Trennzeichen haben, als Bequemlichkeit f├╝r maschinengenerierten Code

Ein Funktionsaufruf in Lua hat die folgende Syntax :

Funktionsaufruf ::= Pr├Ąfixexp-Argumente

Bei einem Funktionsaufruf werden zuerst prefixexp und args ausgewertet

Wenn der Wert von prefixexp vom Typ function ist, wird diese Funktion mit den angegebenen Argumenten aufgerufen

Andernfalls wird die Metamethode prefixexp “call” aufgerufen, die als ersten Parameter den Wert von prefixexp hat, gefolgt von den urspr├╝nglichen Aufrufargumenten (siehe ┬ž2.8)

Die Form

Funktionsaufruf ::= Pr├Ąfixexp `:┬┤ Namensargumente

kann verwendet werden, um “Methoden” aufzurufen

Ein Aufruf v:name(args) ist syntaktischer Zucker f├╝r v.name(v,args) , au├čer dass v nur einmal ausgewertet wird

Argumente haben die folgende Syntax:

args ::= `(┬┤ [explist] `)┬┤ args ::= tableconstructor args ::= string

Alle Argumentausdr├╝cke werden vor dem Aufruf ausgewertet

Ein Aufruf der Form f{fields} ist syntaktischer Zucker f├╝r f({fields}) ; Das hei├čt, die Argumentliste ist eine einzelne neue Tabelle

Ein Aufruf der Form f’string’ (oder f”string” oder f[[string]] ) ist syntaktischer Zucker f├╝r f(‘string’) ; Das hei├čt, die Argumentliste ist eine einzelne Literalzeichenfolge

Als Ausnahme von der Freiformat-Syntax von Lua k├Ânnen Sie in einem Funktionsaufruf keinen Zeilenumbruch vor das ‘ ( ‘ setzen

Diese Einschr├Ąnkung vermeidet einige Mehrdeutigkeiten in der Sprache

Wenn Sie a = f (g).x(a) schreiben, w├╝rde Lua das als eine einzige Aussage sehen, a = f(g).x(a). Wenn Sie also zwei Aussagen wollen, m├╝ssen Sie ein Semi hinzuf├╝gen -Doppelpunkt zwischen ihnen

Wenn Sie f tats├Ąchlich aufrufen wollen, m├╝ssen Sie den Zeilenumbruch vor (g) entfernen

Bei einem Tail-Aufruf verwendet die aufgerufene Funktion den Stack-Eintrag der aufrufenden Funktion erneut

Daher gibt es keine Begrenzung f├╝r die Anzahl verschachtelter Tail-Aufrufe, die ein Programm ausf├╝hren kann

Ein Tail-Aufruf l├Âscht jedoch alle Debug-Informationen ├╝ber die aufrufende Funktion

Beachten Sie, dass ein Tail-Aufruf nur mit einer bestimmten Syntax erfolgt, bei der die R├╝ckgabe einen einzigen Funktionsaufruf als Argument hat; diese Syntax macht den Aufruf functi on return genau die R├╝ckgabe der aufgerufenen Funktion

Keines der folgenden Beispiele ist also ein Tail-Call:

return (f(x)) — Ergebnisse auf 1 angepasst return 2 * f(x) return x, f(x) — zus├Ątzliche Ergebnisse f(x); return — Ergebnisse verworfen return x oder f(x) — Ergebnisse auf 1 angepasst

Die Syntax f├╝r die Funktionsdefinition ist

function ::= function funcbody funcbody ::= `(┬┤ [parlist] `)┬┤ block end

Der folgende syntaktische Zucker vereinfacht Funktionsdefinitionen:

stat ::= function funcname funcbody stat ::= lokaler Funktionsname funcbody funcname ::= Name {`.┬┤ Name} [`:┬┤ Name]

Die Aussage

Funktion f () K├Ârperende

wird ├╝bersetzt in

f = Funktion () K├Ârperende

Die Aussage

function t.a.b.c.f () body end

wird ├╝bersetzt in

t.a.b.c.f = function () body end

Die Aussage

lokale Funktion f () body end

wird ├╝bersetzt in

lokal f; f = Funktion () K├Ârperende

nicht zu

local f = function () K├Ârperende

(Dies macht nur einen Unterschied, wenn der Rumpf der Funktion Verweise auf f enth├Ąlt.)

Eine Funktionsdefinition ist ein ausf├╝hrbarer Ausdruck, dessen Wert vom Typ Funktion ist

Wenn Lua einen Chunk vorkompiliert, werden auch alle seine Funktionsk├Ârper vorkompiliert

Wenn dann Lua die Funktionsdefinition ausf├╝hrt, wird die Funktion instanziiert (oder geschlossen)

Diese Funktionsinstanz (oder Closure) ist der Endwert des Ausdrucks

Unterschiedliche Instanzen derselben Funktion k├Ânnen auf unterschiedliche externe lokale Variablen verweisen und unterschiedliche Umgebungstabellen haben

Parameter fungieren als lokale Variablen, die mit den Argumentwerten: initialisiert werden

parlist ::= Namensliste [`,┬┤ `…┬┤] | `…┬┤

Wenn eine Funktion aufgerufen wird, wird die Liste der Argumente an die L├Ąnge der Liste der Parameter angepasst, es sei denn, die Funktion ist eine variadische oder vararg-Funktion, was durch drei Punkte (‘. .

‘) am Ende ihres Parameters angezeigt wird Liste

Eine vararg-Funktion passt ihre Argumentliste nicht an; Stattdessen sammelt es alle zus├Ątzlichen Argumente und stellt sie der Funktion ├╝ber einen vararg-Ausdruck zur Verf├╝gung, der ebenfalls als drei Punkte geschrieben wird

Der Wert dieses Ausdrucks ist eine Liste aller tats├Ąchlichen zus├Ątzlichen Argumente, ├Ąhnlich einer Funktion mit mehreren Ergebnissen

Wenn ein vararg-Ausdruck innerhalb eines anderen Ausdrucks oder inmitten einer Liste von Ausdr├╝cken verwendet wird, wird seine R├╝ckgabeliste auf ein Element angepasst

See also  Best usenext tipps tricks Update New

Wenn der Ausdruck als letztes Element einer Liste von Ausdr├╝cken verwendet wird, wird keine Anpassung vorgenommen (es sei denn, dieser letzte Ausdruck ist in Klammern eingeschlossen)

Betrachten Sie als Beispiel die folgenden Definitionen:

Funktion f(a, b) Ende Funktion g(a, b,. ..) Ende Funktion r() R├╝ckgabe 1,2,3 Ende

Dann haben wir die folgende Zuordnung von Argumenten zu Parametern und zum vararg-Ausdruck:

AUFRUFPARAMETER f(3) a=3, b=null f(3, 4) a=3, b=4 f(3, 4, 5) a=3, b=4 f(r(), 10) a =1, b=10 f(r()) a=1, b=2 g(3) a=3, b=null,. .

–> (nichts) g(3, 4) a=3, b=4,. .

–> (nichts) g(3, 4, 5, 8) a=3, b=4,. .

–> 5 8 g(5, r()) a=5 , b=1,. .

–> 2 3

Ergebnisse werden mit der return-Anweisung zur├╝ckgegeben (siehe ┬ž2.4.4)

Wenn die Steuerung das Ende einer Funktion erreicht, ohne auf eine return-Anweisung zu sto├čen, kehrt die Funktion ohne Ergebnisse zur├╝ck

Die Doppelpunktsyntax wird zum Definieren von Methoden verwendet, dh Funktionen, die einen impliziten zus├Ątzlichen Parameter self haben

So die Aussage

function t.a.b.c:f (params) body end

ist syntaktischer Zucker f├╝r

t.a.b.c.f = function (self, params) body end

Lua ist eine lexikalisch begrenzte Sprache

Der G├╝ltigkeitsbereich von Variablen beginnt bei der ersten Anweisung nach ihrer Deklaration und dauert bis zum Ende des innersten Blocks, der die Deklaration enth├Ąlt

Betrachten Sie das folgende Beispiel:

x = 10 — globale Variable do — neuer lokaler Block x = x — neues ‘x’, mit Wert 10 print(x) –> 10 x = x+1 do — ein weiterer lokaler Block x = x+1 — ein weiteres ‘x’ print(x) –> 12 end print(x) –> 11 end print(x) –> 10 (das globale)

Beachten Sie, dass in einer Deklaration wie local x = x das neue x, das deklariert wird, noch nicht im G├╝ltigkeitsbereich ist und sich das zweite x daher auf die ├Ąu├čere Variable bezieht

Aufgrund der lexikalischen G├╝ltigkeitsregeln k├Ânnen Funktionen frei auf lokale Variablen zugreifen innerhalb ihres Geltungsbereichs definiert

Eine lokale Variable, die von einer inneren Funktion verwendet wird, wird innerhalb der inneren Funktion als Aufw├Ąrtswert oder externe lokale Variable bezeichnet

Beachten Sie, dass jede Ausf├╝hrung einer lokalen Anweisung neue lokale Variablen definiert

Betrachten Sie das folgende Beispiel:

a = {} local x = 20 for i=1,10 do local y = 0 a[i] = function () y=y+1; R├╝ckgabe x+y Ende Ende

Die Schleife erstellt zehn Closures (also zehn Instanzen der anonymen Funktion)

Jede dieser Closures verwendet eine andere y-Variable, w├Ąhrend alle dasselbe x teilen

Immer wenn w├Ąhrend der Lua-Kompilierung oder -Ausf├╝hrung ein Fehler auftritt, geht die Kontrolle an C zur├╝ck, das geeignete Ma├čnahmen ergreifen kann (z

B

das Drucken einer Fehlermeldung)

Lua-Code kann explizit einen Fehler erzeugen, indem er die Fehlerfunktion aufruft

Wenn Sie Fehler in Lua abfangen m├╝ssen, k├Ânnen Sie die pcall-Funktion verwenden.

Jeder Wert in Lua kann eine Metatabelle haben

Diese Metatabelle ist eine gew├Âhnliche Lua-Tabelle, die das Verhalten des urspr├╝nglichen Werts bei bestimmten speziellen Operationen definiert

Sie k├Ânnen mehrere Aspekte des Verhaltens von Operationen ├╝ber einen Wert ├Ąndern, indem Sie bestimmte Felder in seiner Metatabelle festlegen

Wenn zum Beispiel ein nicht numerischer Wert der Operand einer Addition ist, sucht Lua nach einer Funktion im Feld ÔÇ×__addÔÇť in seiner Metatabelle

Wenn es eine findet, ruft Lua diese Funktion auf, um die Addition durchzuf├╝hren

Wir nennen die Schl├╝ssel in einem metatable events und die Werte metamethods

Im vorherigen Beispiel ist das Ereignis ÔÇ×addÔÇť und die Metamethode ist die Funktion, die die Addition durchf├╝hrt

Sie k├Ânnen die Metatabelle eines beliebigen Werts ├╝ber die Funktion getmetatable abfragen

Sie k├Ânnen die Metatabelle von Tabellen durch die Funktion setmetatable ersetzen

Sie k├Ânnen die Metatabelle anderer Typen von Lua nicht ├Ąndern (au├čer durch Verwendung der Debug-Bibliothek); Sie m├╝ssen daf├╝r die C-API verwenden

Tabellen und vollst├Ąndige Benutzerdaten haben individuelle Metatabellen (obwohl mehrere Tabellen und Benutzerdaten ihre Metatabellen gemeinsam nutzen k├Ânnen)

Werte aller anderen Typen teilen sich eine einzige Metatabelle pro Typ; Das hei├čt, es gibt eine einzige Metatabelle f├╝r alle Zahlen, eine f├╝r alle Zeichenfolgen usw

Eine Metatabelle steuert, wie sich ein Objekt bei arithmetischen Operationen, Ordnungsvergleichen, Verkettungen, L├Ąngenoperationen und Indizierungen verh├Ąlt

Eine Metatabelle kann auch eine Funktion definieren, die aufgerufen werden soll, wenn Benutzerdaten einer Garbage Collection unterzogen werden

F├╝r jede dieser Operationen ordnet Lua einen bestimmten Schl├╝ssel zu, der als Ereignis bezeichnet wird

Wenn Lua eine dieser Operationen auf einen Wert ausf├╝hrt, pr├╝ft es, ob dieser Wert eine Metatabelle mit dem entsprechenden Ereignis hat

Wenn dies der Fall ist, steuert der diesem Schl├╝ssel zugeordnete Wert (die Metamethode), wie Lua die Operation ausf├╝hrt

Metatabellen steuern die als n├Ąchstes aufgef├╝hrten Operationen

Jede Operation wird durch ihren entsprechenden Namen identifiziert

Der Schl├╝ssel f├╝r jede Operation ist eine Zeichenkette, deren Name zwei Unterstriche voranstellen, ‘ __ ‘; Beispielsweise ist der Schl├╝ssel f├╝r die Operation “add” die Zeichenfolge “__add”

Die Semantik dieser Operationen wird besser durch eine Lua-Funktion erkl├Ąrt, die beschreibt, wie der Interpreter die Operation ausf├╝hrt

Der hier in Lua gezeigte Code dient nur der Veranschaulichung; das reale Verhalten ist im Interpreter fest codiert und viel effizienter als diese Simulation

Alle in diesen Beschreibungen verwendeten Funktionen ( rawget , tonumber usw.) sind in ┬ž5.1 beschrieben

Um insbesondere die Metamethode eines bestimmten Objekts abzurufen, verwenden wir den Ausdruck

metatable(obj)[Ereignis]

Dies sollte so gelesen werden

rawget(getmetatable(obj) oder {}, Ereignis)

Das hei├čt, der Zugriff auf eine Metamethode ruft keine anderen Metamethoden auf, und der Zugriff auf Objekte ohne Metatabellen schl├Ągt nicht fehl (er ergibt einfach null)

“add”: die +-Operation

Die Funktion getbinhandler unten definiert, wie Lua einen Handler f├╝r eine bin├Ąre Operation ausw├Ąhlt

Zuerst versucht Lua den ersten Operanden

Wenn sein Typ keinen Handler f├╝r die Operation definiert, versucht Lua den zweiten Operanden

function getbinhandler (op1, op2, event) return metatable(op1)[event] or metatable(op2)[event] end Durch die Verwendung dieser Funktion ist das Verhalten von op1 + op2 function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then — beide Operanden sind numerisch? return o1 + o2 — ‘+’ hier ist das Primitiv ‘add’ else — mindestens einer der Operanden ist nicht numerisch local h = getbinhandler(op1, op2, “__add”) if h then — rufe den Handler mit auf beide Operanden geben (h(op1, op2)) zur├╝ck sonst — kein Handler verf├╝gbar: Standardverhalten error( ) end end end

die Operation

“sub”: die – Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation.

der Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation

“mul”: die *-Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation.

der Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation

“div”: die /-Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation.

der Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation

“mod”: die %-Operation

Verhalten ├Ąhnlich der “add”-Operation, mit der Operation o1 – floor(o1/o2)*o2 als primitiver Operation.

die Operation

Verhalten ├Ąhnlich wie bei der “add”-Operation, wobei die Operation die primitive Operation ist

“pow”: die Operation ^ (Potenzierung)

Verhalten ├Ąhnlich der “add”-Operation, mit der Funktion pow (aus der C-Mathematikbibliothek) als primitiver Operation

Die (Exponentiations-)Operation

Verhalten ├Ąhnlich der “add”-Operation, mit der Funktion (aus der mathematischen C-Bibliothek) als primitiver Operation

“unm”: die un├Ąre – Operation

function unm_event (op) local o = tonumber(op) if o then — Operand ist numerisch? return -o — ‘-‘ hier ist das primitive ‘unm’ else — der Operand ist nicht numerisch

— Versuchen Sie, einen Handler aus dem Operanden local h = metatable(op).__unm zu bekommen if h then — rufen Sie den Handler mit dem Operanden return (h(op)) auf sonst — kein Handler verf├╝gbar: Standardverhalten error(┬Ě┬Ě ┬Ě) Ende Ende Ende

die un├Ąre Operation

“concat”: die. .-Operation (Verkettung)

function concat_event (op1, op2) if (type(op1) == “string” or type(op1) == “number”) and (type(op2) == “string” or type(op2) == “number” ) dann op1 zur├╝ckgeben.

op2 — primitive Zeichenfolgenverkettung sonst lokal h = getbinhandler(op1, op2, “__concat”) if h dann zur├╝ckgeben (h(op1, op2)) sonst Fehler ( ) end end end

die (Verkettungs-) Operation

“len”: die #-Operation

function len_event (op) if type(op) == “string” then return strlen(op) — primitive string length elseif type(op) == “table” then return #op — primitive table length else local h = metatable (op).__len if h then — Aufruf des Handlers mit dem Operanden return (h(op)) else — kein Handler verf├╝gbar: Standardverhalten error( ) end end end Siehe ┬ž2.5.5 f├╝r eine Beschreibung der L├Ąnge von ein Tisch.

die Operation

“eq”: die == Operation

Die Funktion getcomphandler definiert, wie Lua eine Metamethode f├╝r Vergleichsoperatoren ausw├Ąhlt

Eine Metamethode wird nur dann ausgew├Ąhlt, wenn beide zu vergleichenden Objekte denselben Typ und dieselbe Metamethode f├╝r die ausgew├Ąhlte Operation haben

function getcomphandler(op1, op2, event) if type(op1) ~= type(op2) then return nil end local mm1 = metatable(op1)[event] local mm2 = metatable(op2)[event] if mm1 == mm2 then return mm1 else return nil end end Das Ereignis “eq” ist wie folgt definiert: function eq_event (op1, op2) if type(op1) ~= type(op2) then — verschiedene Typen? return false ÔÇô verschiedene Objekte enden if op1 == op2 then ÔÇô primitive equal? return true ÔÇô Objekte sind gleich end ÔÇô try metamethod local h = getcomphandler(op1, op2, “__eq”) if h then return (h(op1, op2)) else return false end end a ~= b ist ├Ąquivalent zu not (a == b).

die Operation

Die Funktion definiert, wie Lua eine Metamethode f├╝r Vergleichsoperatoren ausw├Ąhlt

Eine Metamethode wird nur dann ausgew├Ąhlt, wenn beide zu vergleichenden Objekte denselben Typ und dieselbe Metamethode f├╝r die ausgew├Ąhlte Operation haben

“lt”: die <-Operation

function lt_event (op1, op2) if type(op1) == “number” and type(op2) == “number” then return op1 < op2 -- numerischer Vergleich elseif type(op1) == "string" and type(op2 ) == "string" then return op1 < op2 -- lexikografischer Vergleich else local h = getcomphandler(op1, op2, "__lt") if h then return (h(op1, op2)) else error( ) end end end a > b ist ├Ąquivalent zu b < a.

die Operation

“le”: die <= Operation

function le_event (op1, op2) if type(op1) == “number” and type(op2) == “number” then return op1 <= op2 -- numerischer Vergleich elseif type(op1) == "string" and type( op2) == "string" dann op1 <= op2 -- lexikographischer Vergleich sonst lokal h = getcomphandler(op1, op2, "__le") if h then return (h(op1, op2)) else h = getcomphandler(op1, op2, "__lt") if h then return not h(op2, op1) else error( ) end end end end a >= b ist ├Ąquivalent zu b <= a

Beachten Sie, dass Lua in Ermangelung einer ÔÇ×leÔÇť-Metamethode die ÔÇ×ltÔÇť-Methode versucht, wobei angenommen wird, dass a <= b ├Ąquivalent zu not (b < a) ist.

die Operation

“index”: Die Indizierungszugriffstabelle[Schl├╝ssel]

function gettable_event (table, key) local h if type(table) == “table” then local v = rawget(table, key) if v ~= nil then return v end h = metatable(table).__index if h == nil then return nil end else h = metatable(table).__index if h == nil then error( ) end end if type(h) == “function” then return (h(table, key)) — Rufen Sie den Handler auf sonst h [Taste] zur├╝ckgeben – oder Operation am Ende wiederholen

Der Indizierungszugriff

“newindex”: Die Indizierungszuweisungstabelle[Schl├╝ssel] = Wert

Funktion settable_event (Tabelle, Schl├╝ssel, Wert) local h if type(table) == “table” then local v = rawget(table, key) if v ~= nil then rawset(table, key, value); return end h = metatable(table).__newindex if h == nil then rawset(table, key, value); return end else h = metatable(table).__newindex if h == nil then error( ) end end if type(h) == “function” then h(table, key,value) — rufe den Handler auf else h[key ] = value — oder wiederholen Sie die Operation am Ende Ende

Die Indizierungszuweisung

“call”: Wird aufgerufen, wenn Lua einen Wert aufruft

function function_event (func,. ..) if type(func) == “function” then return func(…) — primitive call else local h = metatable(func).__call if h then return h(func,

..) sonst Fehler(┬Ě┬Ě┬Ě) Ende Ende Ende

Neben Metatabellen haben Objekte der Typen Thread, Function und Userdata eine weitere Tabelle, die mit ihnen verkn├╝pft ist und ihre Umgebung genannt wird

Wie Metatabellen sind Umgebungen regul├Ąre Tabellen, und mehrere Objekte k├Ânnen dieselbe Umgebung teilen

Threads werden erstellt, indem sie die Umgebung des erstellenden Threads teilen

Benutzerdaten und C-Funktionen werden erstellt, indem sie die Umgebung der erstellenden C-Funktion teilen

Nicht verschachtelte Lua-Funktionen (erstellt durch loadfile , loadstring oder load ) werden erstellt, indem sie die Umgebung des erstellenden Threads teilen

Verschachtelte Lua-Funktionen werden erstellt, indem sie die Umgebung der erstellenden Lua-Funktion teilen

Umgebungen, die mit Benutzerdaten verkn├╝pft sind, haben f├╝r Lua keine Bedeutung

Es ist nur eine Komfortfunktion f├╝r Programmierer, eine Tabelle mit Benutzerdaten zu verkn├╝pfen

Mit Threads verkn├╝pfte Umgebungen werden als globale Umgebungen bezeichnet

Sie werden als Standardumgebung f├╝r Threads und nicht verschachtelte Lua-Funktionen verwendet, die vom Thread erstellt werden, und es kann direkt mit C-Code zugegriffen werden (siehe ┬ž3.3)

Auf die mit einer C-Funktion verkn├╝pfte Umgebung kann direkt mit C-Code zugegriffen werden (siehe ┬ž3.3)

Es wird als Standardumgebung f├╝r andere C-Funktionen und Benutzerdaten verwendet, die von der Funktion erstellt werden

Mit Lua-Funktionen verkn├╝pfte Umgebungen werden verwendet, um alle Zugriffe auf globale Variablen innerhalb der Funktion aufzul├Âsen (siehe ┬ž2.3)

Sie werden als Standardumgebung f├╝r verschachtelte Lua-Funktionen verwendet, die von der Funktion erstellt werden

Sie k├Ânnen die Umgebung einer Lua-Funktion oder des laufenden Threads ├Ąndern, indem Sie setfenv aufrufen

Sie k├Ânnen die Umgebung einer Lua-Funktion oder des laufenden Threads abrufen, indem Sie getfenv aufrufen

Um die Umgebung anderer Objekte (Benutzerdaten, C-Funktionen, andere Threads) zu manipulieren, m├╝ssen Sie die C-API verwenden

Lua f├╝hrt eine automatische Speicherverwaltung durch

Das bedeutet, dass Sie sich weder darum k├╝mmern m├╝ssen, Speicher f├╝r neue Objekte zuzuweisen, noch ihn freizugeben, wenn die Objekte nicht mehr ben├Âtigt werden

Lua verwaltet den Speicher automatisch, indem es von Zeit zu Zeit einen Garbage Collector ausf├╝hrt, um alle toten Objekte (dh Objekte, auf die Lua nicht mehr zugreifen kann) zu sammeln

Der gesamte von Lua verwendete Speicher unterliegt einer automatischen Verwaltung: Tabellen, Benutzerdaten, Funktionen, Threads, Strings usw

Lua implementiert einen inkrementellen Mark-and-Sweep-Kollektor

Es verwendet zwei Zahlen, um seine Garbage-Collection-Zyklen zu steuern: die Garbage-Collector-Pause und den Garbage-Collector-Schrittmultiplikator

Beide verwenden Prozentpunkte als Einheiten (so dass ein Wert von 100 einen internen Wert von 1 bedeutet)

Die Garbage-Collector-Pause steuert, wie lange der Collector wartet, bevor er einen neuen Zyklus startet

Gr├Â├čere Werte machen den Sammler weniger aggressiv

Werte kleiner als 100 bedeuten, dass der Kollektor nicht wartet, um einen neuen Zyklus zu starten

Ein Wert von 200 bedeutet, dass der Kollektor wartet, bis sich der verwendete Gesamtspeicher verdoppelt hat, bevor er einen neuen Zyklus startet.

Der Schrittmultiplikator steuert die relative Geschwindigkeit des Kollektors relativ zur Speicherzuweisung

Gr├Â├čere Werte machen den Kollektor aggressiver, erh├Âhen aber auch die Gr├Â├če jedes inkrementellen Schritts

Werte kleiner als 100 machen den Kollektor zu langsam und k├Ânnen dazu f├╝hren, dass der Kollektor einen Zyklus nie beendet

Der Standardwert 200 bedeutet, dass der Kollektor mit der “doppelten” Geschwindigkeit der Speicherzuweisung l├Ąuft

Sie k├Ânnen diese Zahlen ├Ąndern, indem Sie lua_gc in C oder collectgarbage in Lua aufrufen

Mit diesen Funktionen k├Ânnen Sie den Collector auch direkt steuern (z

B

stoppen und neu starten)

Mit der C-API k├Ânnen Sie Garbage-Collector-Metamethoden f├╝r Benutzerdaten festlegen (siehe ┬ž2.8)

Diese Metamethoden werden auch als Finalizer bezeichnet

Mit Finalizern k├Ânnen Sie die Garbage Collection von Lua mit der externen Ressourcenverwaltung koordinieren (z

B

das Schlie├čen von Dateien, Netzwerk- oder Datenbankverbindungen oder das Freigeben Ihres eigenen Speichers)

Garbage-Benutzerdaten mit einem Feld __gc in ihren Metatabellen werden nicht sofort vom Garbage Collector gesammelt

Stattdessen f├╝gt Lua sie in eine Liste ein

Nach der Sammlung führt Lua das Äquivalent der folgenden Funktion für alle Benutzerdaten in dieser Liste aus:

function gc_event (udata) local h = metatable(udata).__gc if h then h(udata) end end

Am Ende jedes Garbage-Collection-Zyklus werden die Finalizer f├╝r Benutzerdaten in umgekehrter Reihenfolge ihrer Erstellung unter den in diesem Zyklus gesammelten aufgerufen

Das hei├čt, der erste aufgerufene Finalizer ist derjenige, der den zuletzt im Programm erstellten Benutzerdaten zugeordnet ist

Die Benutzerdaten selbst werden erst im n├Ąchsten Garbage-Collection-Zyklus freigegeben

Eine schwache Tabelle ist eine Tabelle, deren Elemente schwache Referenzen sind

Eine schwache Referenz wird vom Garbage Collector ignoriert

Mit anderen Worten, wenn die einzigen Referenzen auf ein Objekt schwache Referenzen sind, wird der Garbage Collector dieses Objekt einsammeln

Eine schwache Tabelle kann schwache Schl├╝ssel, schwache Werte oder beides haben

Eine Tabelle mit schwachen Schl├╝sseln erlaubt das Sammeln ihrer Schl├╝ssel, verhindert aber das Sammeln ihrer Werte

Eine Tabelle mit schwachen Schl├╝sseln und schwachen Werten erm├Âglicht die Erfassung von Schl├╝sseln und Werten

In jedem Fall wird, wenn entweder der Schl├╝ssel oder der Wert gesammelt wird, das gesamte Paar aus der Tabelle entfernt

Die Schw├Ąche einer Tabelle wird durch das __mode-Feld ihrer Metatabelle gesteuert

Wenn das Feld __mode eine Zeichenfolge ist, die das Zeichen ‘ k ‘ enth├Ąlt, sind die Schl├╝ssel in der Tabelle schwach

Wenn __mode ÔÇ×vÔÇť enth├Ąlt, sind die Werte in der Tabelle schwach.

Nachdem Sie eine Tabelle als Metatabelle verwendet haben, sollten Sie den Wert ihres __mode-Felds nicht ├Ąndern

Andernfalls ist das schwache Verhalten der Tabellen, die von dieser Metatabelle gesteuert werden, undefiniert

Lua unterst├╝tzt Coroutinen, auch kollaboratives Multithreading genannt

Eine Coroutine in Lua repr├Ąsentiert einen unabh├Ąngigen Ausf├╝hrungsthread

Im Gegensatz zu Threads in Multithread-Systemen setzt eine Coroutine ihre Ausf├╝hrung jedoch nur aus, indem sie explizit eine yield-Funktion aufruft

Sie erstellen eine Coroutine mit einem Aufruf von coroutine.create

Sein einziges Argument ist eine Funktion, die die Hauptfunktion der Coroutine ist

Die create-Funktion erstellt nur eine neue Coroutine und gibt ihr ein Handle zur├╝ck (ein Objekt vom Typ Thread); Die Ausf├╝hrung der Coroutine wird nicht gestartet

Wenn Sie coroutine.resume zum ersten Mal aufrufen und als erstes Argument einen von coroutine.create zur├╝ckgegebenen Thread ├╝bergeben, beginnt die Coroutine ihre Ausf├╝hrung in der ersten Zeile ihrer Hauptfunktion

Zus├Ątzliche Argumente, die an coroutine.resume ├╝bergeben werden, werden an die Hauptfunktion der Coroutine ├╝bergeben

Nachdem die Coroutine gestartet wurde, l├Ąuft sie, bis sie beendet wird oder nachgibt

Eine Coroutine kann ihre Ausf├╝hrung auf zwei Arten beenden: normalerweise, wenn ihre Hauptfunktion zur├╝ckkehrt (explizit oder implizit, nach der letzten Anweisung); und anormal, wenn ein ungesch├╝tzter Fehler vorliegt

Im ersten Fall gibt coroutine.resume true zur├╝ck, plus alle Werte, die von der Hauptfunktion der Coroutine zur├╝ckgegeben werden

Im Fehlerfall gibt coroutine.resume false plus eine Fehlermeldung zur├╝ck.

Eine Coroutine gibt nach, indem sie coroutine.yield aufruft

Wenn eine Coroutine ergibt, kehrt die entsprechende coroutine.resume sofort zur├╝ck, selbst wenn die R├╝ckgabe innerhalb verschachtelter Funktionsaufrufe erfolgt (d

h

nicht in der Hauptfunktion, sondern in einer Funktion, die direkt oder indirekt von der Hauptfunktion aufgerufen wird)

Im Falle eines yield gibt coroutine.resume auch true zur├╝ck, plus alle an coroutine.yield ├╝bergebenen Werte

Wenn Sie dieselbe Coroutine das n├Ąchste Mal fortsetzen, setzt sie ihre Ausf├╝hrung an dem Punkt fort, an dem sie aufgegeben wurde, wobei der Aufruf von coroutine.yiel alle zus├Ątzlichen Argumente zur├╝ckgibt, die an coroutine.resume ├╝bergeben wurden

Wie coroutine.create erstellt auch die Funktion coroutine.wrap eine Coroutine, aber anstatt die Coroutine selbst zur├╝ckzugeben, gibt sie eine Funktion zur├╝ck, die, wenn sie aufgerufen wird, die Coroutine fortsetzt

Alle an diese Funktion ├╝bergebenen Argumente gehen als zus├Ątzliche Argumente an coroutine.resume

coroutine.wrap gibt alle von coroutine.resume zur├╝ckgegebenen Werte zur├╝ck, mit Ausnahme des ersten (dem booleschen Fehlercode)

Im Gegensatz zu coroutine.resume f├Ąngt coroutine.wrap keine Fehler ab; Jeder Fehler wird an den Aufrufer weitergegeben

Betrachten Sie als Beispiel den folgenden Code:

function foo (a) print(“foo”, a) return coroutine.yield(2*a) end co = coroutine.create(function (a,b) print(“co-body”, a, b) local r = foo(a+1) print(“co-body”, r) local r, s = coroutine.yield(a+b, ab) print(“co-body”, r, s) return b, “end” end ) print(“main”, coroutine.resume(co, 1, 10)) print(“main”, coroutine.resume(co, “r”)) print(“main”, coroutine.resume(co, “x” , “y”)) print(“main”, coroutine.resume(co, “x”, “y”))

Wenn Sie es ausf├╝hren, erzeugt es die folgende Ausgabe:

co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false tote Koroutine kann nicht fortgesetzt werden

3 – Die Anwendungsprogrammschnittstelle

Dieser Abschnitt beschreibt die C-API f├╝r Lua, d

h

den Satz von C-Funktionen, die dem Hostprogramm zur Kommunikation mit Lua zur Verf├╝gung stehen

Alle API-Funktionen und zugeh├Ârige Typen und Konstanten sind in der Header-Datei lua.h deklariert

Selbst wenn wir den Begriff ÔÇ×FunktionÔÇť verwenden, kann jede Einrichtung in der API stattdessen als Makro bereitgestellt werden

Alle diese Makros verwenden jedes ihrer Argumente genau einmal (mit Ausnahme des ersten Arguments, das immer ein Lua-Zustand ist) und erzeugen daher keine versteckten Nebeneffekte

Wie in den meisten C-Bibliotheken pr├╝fen die Lua-API-Funktionen nicht ihre Argumente f├╝r G├╝ltigkeit oder Konsistenz

Sie k├Ânnen dieses Verhalten jedoch ├Ąndern, indem Sie Lua mit einer geeigneten Definition f├╝r das Makro luai_apicheck in der Datei luaconf.h kompilieren

Lua verwendet einen virtuellen Stack, um Werte an und von C zu ├╝bergeben

Jedes Element in diesem Stack repr├Ąsentiert einen Lua-Wert (nil , Zahl, Zeichenfolge usw.)

Immer wenn Lua C aufruft, erh├Ąlt die aufgerufene Funktion einen neuen Stack, der unabh├Ąngig von vorherigen Stacks und Stacks von C-Funktionen ist, die noch aktiv sind

Dieser Stack enth├Ąlt anfangs alle Argumente f├╝r die C-Funktion, und dort schiebt die C-Funktion ihre Ergebnisse zur R├╝ckgabe an den Aufrufer (siehe lua_CFunction )

Der Einfachheit halber folgen die meisten Abfrageoperationen in der API keiner strikten Stack-Disziplin

Stattdessen k├Ânnen sie auf jedes Element im Stapel verweisen, indem sie einen Index verwenden: Ein positiver Index repr├Ąsentiert eine absolute Stapelposition (beginnend bei 1); ein negativer Index stellt einen Versatz relativ zur Spitze des Stapels dar

Genauer gesagt, wenn der Stack n Elemente hat, stellt Index 1 das erste Element dar (d

h

das Element, das zuerst auf den Stack geschoben wurde) und Index n stellt das letzte Element dar; Index -1 repr├Ąsentiert auch das letzte Element (d

h

das Element ganz oben) und Index -n repr├Ąsentiert das erste Element

Wir sagen, dass ein Index g├╝ltig ist, wenn er zwischen 1 und dem Stack-Top liegt (d

h

wenn 1 ÔëĄ abs(index) ÔëĄ top )

Wenn Sie mit der Lua-API interagieren, sind Sie daf├╝r verantwortlich, Konsistenz sicherzustellen

Insbesondere sind Sie f├╝r die Kontrolle des Stapel├╝berlaufs verantwortlich

Sie k├Ânnen die Funktion lua_checkstack verwenden, um die Stapelgr├Â├če zu vergr├Â├čern.

Immer wenn Lua C aufruft, stellt es sicher, dass mindestens LUA_MINSTACK-Stack-Positionen verf├╝gbar sind

LUA_MINSTACK ist als 20 definiert, sodass Sie sich normalerweise keine Gedanken ├╝ber den Stapelspeicher machen m├╝ssen, es sei denn, Ihr Code hat Schleifen, die Elemente auf den Stapel schieben

Die meisten Abfragefunktionen akzeptieren als Indizes jeden Wert innerhalb des verf├╝gbaren Stapelspeichers, dh Indizes bis zu die maximale Stapelgr├Â├če, die Sie ├╝ber lua_checkstack festgelegt haben

Solche Indizes werden als akzeptable Indizes bezeichnet

Formaler definieren wir einen akzeptablen Index wie folgt:

(Index < 0 && abs(Index) <= oben) || (Index > 0 && Index <= Stackspace)

Beachten Sie, dass 0 niemals ein akzeptabler Index ist

Sofern nicht anders angegeben, kann jede Funktion, die g├╝ltige Indizes akzeptiert, auch mit Pseudo-Indizes aufgerufen werden, die einige Lua-Werte darstellen, die f├╝r C-Code zug├Ąnglich sind, sich aber nicht im Stack befinden

Pseudo-Indizes werden verwendet, um auf die Thread-Umgebung, die Funktionsumgebung, die Registrierung und die Aufw├Ąrtswerte einer C-Funktion zuzugreifen (siehe ┬ž3.4)

Die Thread-Umgebung (in der sich globale Variablen befinden) befindet sich immer am Pseudo-Index LUA_GLOBALSINDEX

Die Umgebung der laufenden C-Funktion befindet sich immer am Pseudo-Index LUA_ENVIRONINDEX.

Um auf globale Variablen zuzugreifen und deren Werte zu ├Ąndern, k├Ânnen Sie regul├Ąre Tabellenoperationen ├╝ber eine Umgebungstabelle verwenden

Um beispielsweise auf den Wert einer globalen Variablen zuzugreifen, tun Sie

lua_getfield(L, LUA_GLOBALSINDEX, Variablenname);

Wenn eine C-Funktion erstellt wird, ist es m├Âglich, ihr einige Werte zuzuordnen, wodurch eine C-Closure erstellt wird; diese Werte werden Aufw├Ąrtswerte genannt und sind der Funktion bei jedem Aufruf zug├Ąnglich (siehe lua_pushcclosure)

Immer wenn eine C-Funktion aufgerufen wird, befinden sich ihre Aufw├Ąrtswerte an bestimmten Pseudo-Indizes

Diese Pseudo-Indizes werden vom Makro lua_upvalueindex erzeugt

Der erste einer Funktion zugeordnete Wert befindet sich an Position lua_upvalueindex(1) und so weiter

Jeder Zugriff auf lua_upvalueindex(n) , wobei n gr├Â├čer als die Anzahl der Aufw├Ąrtswerte der aktuellen Funktion (aber nicht gr├Â├čer als 256) ist, erzeugt einen akzeptablen (aber ung├╝ltigen) Index

Lua stellt eine Registrierung bereit, eine vordefinierte Tabelle, die von jedem C-Code verwendet werden kann, um jeden Lua-Wert zu speichern, den er speichern muss

Diese Tabelle befindet sich immer am Pseudo-Index LUA_REGISTRYINDEX

Jede C-Bibliothek kann Daten in dieser Tabelle speichern, aber sie sollte darauf achten, Schl├╝ssel zu w├Ąhlen, die sich von denen anderer Bibliotheken unterscheiden, um Kollisionen zu vermeiden

Normalerweise sollten Sie als Schl├╝ssel einen String verwenden, der Ihren Bibliotheksnamen enth├Ąlt, oder leichte Benutzerdaten mit der Adresse eines C-Objekts in Ihrem Code

Die Integer-Schl├╝ssel in der Registrierung werden vom Referenzmechanismus verwendet, der von der Hilfsbibliothek implementiert wird, und daher sollte nicht f├╝r andere Zwecke verwendet werden

Lua verwendet intern die C-longjmp-Einrichtung, um Fehler zu behandeln

(Sie k├Ânnen auch Ausnahmen verwenden, wenn Sie C++ verwenden; siehe Datei luaconf.h. ) Wenn Lua auf einen Fehler st├Â├čt (wie Speicherzuordnungsfehler, Typfehler, Syntaxfehler und Laufzeitfehler), l├Âst es einen Fehler aus; das hei├čt, es macht einen Weitsprung

Eine gesch├╝tzte Umgebung verwendet setjmp, um einen Wiederherstellungspunkt festzulegen; Jeder Fehler springt zum letzten aktiven Wiederherstellungspunkt

Die meisten Funktionen in der API k├Ânnen einen Fehler ausl├Âsen, beispielsweise aufgrund eines Speicherzuweisungsfehlers

Die Dokumentation f├╝r jede Funktion gibt an, ob sie Fehler werfen kann

Innerhalb einer C-Funktion k├Ânnen Sie einen Fehler werfen, indem Sie lua_error aufrufen

Hier listen wir alle Funktionen und Typen der C-API in alphabetischer Reihenfolge auf

Jede Funktion hat einen Indikator wie diesen: [-o, +p, x]

Das erste Feld, o , gibt an, wie viele Elemente die Funktion aus dem Stapel holt

Das zweite Feld, p , gibt an, wie viele Elemente die Funktion auf den Stapel legt

(Jede Funktion pusht ihre Ergebnisse immer, nachdem sie ihre Argumente entfernt hat.) Ein Feld in der Form x|y bedeutet, dass die Funktion je nach Situation x oder y Elemente pushen (oder poppen) kann; ein Fragezeichen ‘ ? ‘ bedeutet, dass wir nicht wissen k├Ânnen, wie viele Elemente die Funktion auftaucht/dr├╝ckt, indem wir nur ihre Argumente betrachten (z

B

k├Ânnen sie davon abh├Ąngen, was sich auf dem Stapel befindet)

Das dritte Feld, x , gibt an, ob die Funktion Fehler ausgeben darf: ‘ – ‘ bedeutet, dass die Funktion niemals einen Fehler ausgibt; ‘ m ‘ bedeutet, dass die Funktion nur aufgrund von nicht gen├╝gend Speicher einen Fehler ausgeben kann; ‘e’ bedeutet, dass die Funktion andere Arten von Fehlern ausl├Âsen kann; ‘ v ‘ bedeutet, dass die Funktion absichtlich einen Fehler ausgeben kann.

typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);

Der Typ der von Lua verwendeten Speicherzuweisungsfunktion gibt an

Die Zuweisungsfunktion muss eine ├Ąhnliche Funktionalit├Ąt wie realloc bereitstellen, aber nicht genau die gleiche

Seine Argumente sind ud , ein undurchsichtiger Zeiger, der an lua_newstate ├╝bergeben wird; ptr , ein Zeiger auf den Block, der zugewiesen/neu zugewiesen/freigegeben wird; osize , die urspr├╝ngliche Gr├Â├če des Blocks; nsize , die neue Gr├Â├če des Blocks

ptr ist genau dann NULL, wenn osize null ist

Wenn nsize Null ist, muss der Zuordner NULL zur├╝ckgeben; Wenn osize nicht null ist, sollte es den Block freigeben, auf den ptr zeigt

Wenn nsize nicht Null ist, gibt der Zuordner NULL zur├╝ck, wenn und nur wenn er die Anforderung nicht erf├╝llen kann

Wenn nsize nicht null und osize null ist, sollte sich der Allocator wie malloc verhalten

Wenn nsize und osize nicht Null sind, verh├Ąlt sich der Allocator wie realloc

Lua geht davon aus, dass der Allocator niemals fehlschl├Ągt, wenn osize >= nsize.

Hier ist eine einfache Implementierung f├╝r die Allocator-Funktion

Es wird in der Hilfsbibliothek von luaL_newstate verwendet

static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { (void)ud; (leer)gr├Â├če; /* nicht verwendet */ if (nsize == 0) { free(ptr); gib NULL zur├╝ck; } Sonst realloc(ptr, nsize) zur├╝ckgeben; }

Dieser Code geht davon aus, dass free(NULL) keine Auswirkung hat und dass realloc(NULL, size) ├Ąquivalent zu malloc(size) ist

ANSI C gew├Ąhrleistet beide Verhaltensweisen.

[-0, +0, -]

lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);

Setzt eine neue Panic-Funktion und gibt die alte zur├╝ck

Wenn ein Fehler au├čerhalb einer gesch├╝tzten Umgebung auftritt, ruft Lua eine Panic-Funktion auf und ruft dann exit(EXIT_FAILURE) auf, wodurch die Host-Anwendung beendet wird

Ihre Panikfunktion kann diesen Ausgang vermeiden, indem sie niemals zur├╝ckkehrt (z

B

einen Weitsprung macht)

Die Panikfunktion kann auf die Fehlermeldung am Anfang des Stapels zugreifen.

[-(nargs + 1), +nresults, e]

void lua_call (lua_State *L, int nargs, int nresults);

Ruft eine Funktion auf

Um eine Funktion aufzurufen, m├╝ssen Sie das folgende Protokoll verwenden: Zuerst wird die aufzurufende Funktion auf den Stack geschoben; dann werden die Argumente der Funktion in direkter Reihenfolge geschoben; Das hei├čt, das erste Argument wird zuerst verschoben

Schlie├člich rufen Sie lua_call auf; nargs ist die Anzahl der Argumente, die Sie auf den Stack geschoben haben

Alle Argumente und der Funktionswert werden beim Aufruf der Funktion aus dem Stack geholt

Die Funktionsergebnisse werden auf den Stapel geschoben, wenn die Funktion zur├╝ckkehrt

Die Anzahl der Ergebnisse wird an nresults angepasst, es sei denn, nresults ist LUA_MULTRET

In diesem Fall werden alle Ergebnisse der Funktion gepusht

Lua k├╝mmert sich darum, dass die zur├╝ckgegebenen Werte in den Stackspace passen

Die Funktionsergebnisse werden in direkter Reihenfolge auf den Stack geschoben (das erste Ergebnis wird zuerst geschoben), sodass nach dem Aufruf das letzte Ergebnis ganz oben auf dem Stack steht

Jeder Fehler innerhalb der aufgerufenen Funktion wird nach oben propagiert (mit einem longjmp ).

Das folgende Beispiel zeigt, wie das Host-Programm das Äquivalent zu diesem Lua-Code ausführen kann:

a = f(“wie”, t.x, 14)

Hier ist es in C:

lua_getfield(L, LUA_GLOBALSINDEX, “f”); /* aufzurufende Funktion */ lua_pushstring(L, “how”); /* 1

Argument */ lua_getfield(L, LUA_GLOBALSINDEX, “t”); /* zu indexierende Tabelle */ lua_getfield(L, -1, “x”); /* Push-Ergebnis von t.x (2

Argument) */ lua_remove(L, -2); /* ‘t’ vom Stack entfernen */ lua_pushinteger(L, 14); /* 3

Argument */ lua_call(L, 3, 1); /* Aufruf von ‘f’ mit 3 Argumenten und 1 Ergebnis */ lua_setfield(L, LUA_GLOBALSINDEX, “a”); /* globales ‘a’ setzen */

Beachten Sie, dass der obige Code “ausgeglichen” ist: Am Ende befindet sich der Stack wieder in seiner urspr├╝nglichen Konfiguration

Dies gilt als gute Programmierpraxis.

typedef int (*lua_CFunction) (lua_State *L);

Typ f├╝r C-Funktionen.

Um richtig mit Lua zu kommunizieren, muss eine C-Funktion das folgende Protokoll verwenden, das die Art und Weise definiert, wie Parameter und Ergebnisse ├╝bergeben werden: Eine C-Funktion erh├Ąlt ihre Argumente von Lua in ihrem Stack in direkter Reihenfolge (die erste Argument wird zuerst verschoben)

Wenn also die Funktion startet, gibt lua_gettop(L) die Anzahl der von der Funktion empfangenen Argumente zur├╝ck

Das erste Argument (falls vorhanden) befindet sich bei Index 1 und sein letztes Argument befindet sich bei Index lua_gettop(L)

Um Werte an Lua zur├╝ckzugeben, schiebt eine C-Funktion sie einfach in direkter Reihenfolge auf den Stack (das erste Ergebnis wird zuerst geschoben) und gibt die Anzahl der Ergebnisse zur├╝ck

Jeder andere Wert im Stapel unterhalb der Ergebnisse wird von Lua ordnungsgem├Ą├č verworfen

Wie eine Lua-Funktion kann auch eine von Lua aufgerufene C-Funktion viele Ergebnisse zur├╝ckgeben

Als Beispiel erh├Ąlt die folgende Funktion eine variable Anzahl numerischer Argumente und gibt deren Durchschnitt und Summe zur├╝ck:

Statisch int foo (lua_State *L) { int n = lua_gettop(L); /* Anzahl der Argumente */ lua_Number sum = 0; int ich; for (i = 1; i <= n; i++) { if (!lua_isnumber(L, i)) { lua_pushstring(L, "falsches Argument"); lua_error(L); } Summe += lua_tonumber(L, i); } lua_pushnumber(L, Summe/n); /* erstes Ergebnis */ lua_pushnumber(L, sum); /* zweites Ergebnis */ return 2; /* Anzahl der Ergebnisse */ }

[-0, +0, m]

int lua_checkstack (lua_State *L, int extra);

Stellt sicher, dass mindestens zus├Ątzliche freie Stapelpl├Ątze im Stapel vorhanden sind

Es gibt false zur├╝ck, wenn der Stack nicht auf diese Gr├Â├če wachsen kann

Diese Funktion verkleinert niemals den Stack; wenn der Stack bereits gr├Â├čer als die neue Gr├Â├če ist, wird er unver├Ąndert gelassen

[-0, +0, -]

void lua_close (lua_State *L);

Zerst├Ârt alle Objekte im angegebenen Lua-Zustand (unter Aufruf der entsprechenden Garbage-Collection-Metamethoden, falls vorhanden) und gibt den gesamten dynamischen Speicher frei, der von diesem Zustand verwendet wird

Auf einigen Plattformen m├╝ssen Sie diese Funktion m├Âglicherweise nicht aufrufen, da alle Ressourcen nat├╝rlich freigegeben werden, wenn das Hostprogramm endet

Andererseits m├╝ssen langlaufende Programme wie ein Daemon oder ein Webserver m├Âglicherweise Zust├Ąnde freigeben, sobald sie nicht ben├Âtigt werden, um nicht zu gro├č zu werden

[-n, +1, e]

void lua_concat(lua_State *L, int n);

Verkettet die n Werte ganz oben im Stack, f├╝gt sie ein und l├Ąsst das Ergebnis ganz oben

Wenn n 1 ist, ist das Ergebnis der einzelne Wert auf dem Stapel (dh die Funktion macht nichts); wenn n 0 ist, ist das Ergebnis die leere Zeichenkette

Die Verkettung erfolgt nach der ├╝blichen Semantik von Lua (siehe ┬ž2.5.4)

[-0, +(0|1), -]

int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);

Ruft die C-Funktion func im gesch├╝tzten Modus auf

func beginnt mit nur einem Element in seinem Stack, einem leichten userdata, das ud enth├Ąlt

Im Falle von Fehlern gibt lua_cpcall die gleichen Fehlercodes wie lua_pcall zur├╝ck, plus das Fehlerobjekt oben auf dem Stapel; andernfalls gibt es Null zur├╝ck und ├Ąndert den Stack nicht

Alle von func zur├╝ckgegebenen Werte werden verworfen

[-0, +1, m]

void lua_createtable(lua_State *L, int narr, int nrec);

Erstellt eine neue leere Tabelle und schiebt sie auf den Stack

In der neuen Tabelle ist Speicherplatz f├╝r narr-Array-Elemente und nrec-Nicht-Array-Elemente vorab zugewiesen

Diese Vorbelegung ist n├╝tzlich, wenn Sie genau wissen, wie viele Elemente die Tabelle haben wird

Andernfalls k├Ânnen Sie die Funktion lua_newtable.

[-0, +0, m] verwenden

int lua_dump (lua_State *L, lua_Writer Writer, void *data);

Gibt eine Funktion als bin├Ąren Chunk aus

Empf├Ąngt eine Lua-Funktion oben auf dem Stack und erzeugt einen bin├Ąren Chunk, der, wenn er erneut geladen wird, zu einer Funktion f├╝hrt, die der ausgegebenen entspricht

W├Ąhrend es Teile des Chunks erzeugt, ruft lua_dump die Funktion Writer (siehe lua_Writer ) mit den angegebenen Daten auf, um sie zu schreiben

Der zur├╝ckgegebene Wert ist der Fehlercode, der vom letzten Aufruf an den Writer zur├╝ckgegeben wurde; 0 bedeutet keine Fehler.

Diese Funktion entfernt die Lua-Funktion nicht vom Stack.

[-0, +0, e]

int lua_equal (lua_State *L, int index1, int index2);

Gibt 1 zur├╝ck, wenn die beiden Werte in den akzeptablen Indizes index1 und index2 gleich sind, gem├Ą├č der Semantik des Operators Lua == (d

h

kann Metamethoden aufrufen)

Gibt andernfalls 0 zur├╝ck

Gibt auch 0 zur├╝ck, wenn einer der Indizes ung├╝ltig ist

[-1, +0, v]

int lua_error (lua_State *L);

Erzeugt einen Lua-Fehler

Die Fehlermeldung (die eigentlich ein beliebiger Lua-Wert sein kann) muss ganz oben auf dem Stack stehen

Diese Funktion macht einen langen Sprung und kehrt daher nie zur├╝ck

(siehe luaL_error ).

[-0, +0, e]

int lua_gc (lua_State *L, int was, int data);

Steuert den Garbage Collector

Diese Funktion f├╝hrt je nach Wert des Parameters what : mehrere Aufgaben aus

LUA_GCSTOP : stoppt den Garbage Collector

stoppt den Garbage Collector

LUA_GCRESTART : startet den Garbage Collector neu.

startet den Garbage Collector neu

LUA_GCCOLLECT : f├╝hrt einen vollst├Ąndigen Garbage-Collection-Zyklus durch

LUA_GCCOUNT : gibt die aktuelle Speichermenge (in Kbytes) zur├╝ck, die von Lua verwendet wird

LUA_GCCOUNTB : gibt den Rest der Division der aktuellen Bytes des von Lua verwendeten Speichers durch 1024 zur├╝ck.

gibt den Rest der Division der aktuellen Bytes des von Lua verwendeten Speichers durch 1024 zur├╝ck

LUA_GCSTEP : f├╝hrt einen inkrementellen Schritt der Speicherbereinigung durch

Die “Gr├Â├če” der Schritte wird auf nicht spezifizierte Weise durch Daten gesteuert (gr├Â├čere Werte bedeuten mehr Schritte)

Wenn Sie die Schrittgr├Â├če steuern m├Âchten, m├╝ssen Sie den Wert von data experimentell anpassen

Die Funktion gibt 1 zur├╝ck, wenn der Schritt einen Garbage-Collection-Zyklus beendet hat

f├╝hrt einen inkrementellen Schritt der Garbage-Collection durch

Die Schrittgr├Â├če wird durch (gr├Â├čere Werte bedeuten mehr Schritte) auf nicht spezifizierte Weise gesteuert

See also  Top lehrstellen in sachsen New Update

Wenn Sie die Schrittweite steuern m├Âchten, m├╝ssen Sie den Wert von experimentell anpassen

Die Funktion gibt 1 zur├╝ck, wenn der Schritt einen Garbage-Collection-Zyklus beendet hat

LUA_GCSETPAUSE : setzt Daten als neuen Wert f├╝r die Pause des Kollektors (siehe ┬ž2.10)

Die Funktion gibt den vorherigen Wert der Pause zur├╝ck.

stellt den neuen Wert f├╝r die Pause des Kollektors ein (siehe ┬ž2.10)

Die Funktion gibt den vorherigen Wert der Pause zur├╝ck

LUA_GCSETSTEPMUL : setzt Daten als neuen Wert f├╝r den Schrittmultiplikator des Kollektors (siehe ┬ž2.10)

Die Funktion gibt den vorherigen Wert des Schrittmultiplikators zur├╝ck.

[-0, +0, -]

lua_Alloc lua_getallocf (lua_State *L, void **ud);

Gibt die Speicherzuweisungsfunktion eines bestimmten Zustands zur├╝ck

Wenn ud nicht NULL ist, speichert Lua in *ud den undurchsichtigen Zeiger, der an lua_newstate.

[-0, +1, -] ├╝bergeben wurde

void lua_getfenv (lua_State *L, int index);

Schiebt die Umgebungstabelle des Werts am gegebenen Index auf den Stack

[-0, +1, e]

void lua_getfield(lua_State *L, int index, const char *k);

Legt den Wert t[k] auf den Stack, wobei t der Wert am gegebenen g├╝ltigen Index ist

Wie in Lua kann diese Funktion eine Metamethode f├╝r das “index”-Ereignis ausl├Âsen (siehe ┬ž2.8).

[-0, +1, e]

void lua_getglobal(lua_State *L, const char *name);

Legt den Wert des globalen Namens auf den Stack

Es ist als Makro definiert:

#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)

[-0, +(0|1), -]

int lua_getmetatable (lua_State *L, int index);

Schiebt die Metatabelle des Werts am gegebenen akzeptablen Index auf den Stack

Wenn der Index ung├╝ltig ist oder der Wert keine Metatabelle hat, gibt die Funktion 0 zur├╝ck und legt nichts auf den Stapel

[-1, +1, e]

void lua_gettable (lua_State *L, int index);

Legt den Wert t[k] auf den Stapel, wobei t der Wert am gegebenen g├╝ltigen Index und k der Wert ganz oben auf dem Stapel ist

Diese Funktion holt den Schl├╝ssel aus dem Stapel (wobei der resultierende Wert an seine Stelle gesetzt wird )

Wie in Lua kann diese Funktion eine Metamethode f├╝r das “Index”-Ereignis ausl├Âsen (siehe ┬ž2.8).

[-0, +0, -]

int lua_gettop(lua_State *L);

Gibt den Index des obersten Elements im Stack zur├╝ck

Da Indizes bei 1 beginnen, ist dieses Ergebnis gleich der Anzahl der Elemente im Stack (also bedeutet 0 einen leeren Stack)

[-1, +1, -]

void lua_insert(lua_State *L, int index);

Verschiebt das oberste Element in den angegebenen g├╝ltigen Index und verschiebt die Elemente ├╝ber diesem Index nach oben, um Platz zu schaffen

Kann nicht mit einem Pseudo-Index aufgerufen werden, da ein Pseudo-Index keine tats├Ąchliche Stack-Position ist.

typedef ptrdiff_t lua_Integer;

Der Typ, der von der Lua-API verwendet wird, um ganzzahlige Werte darzustellen

int lua_isboolean (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index den Typ boolean hat, andernfalls 0.

[-0, +0, -]

int lua_iscfunction (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index eine C-Funktion ist, andernfalls 0.

[-0, +0, -]

int lua_isfunction (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index eine Funktion ist (entweder C oder Lua), andernfalls 0.

[-0, +0, -]

int lua_islightuserdata(lua_State *L, int index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index leichte Benutzerdaten ist, andernfalls 0.

[-0, +0, -]

int lua_isnil (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index Null ist, andernfalls 0.

[-0, +0, -]

int lua_isnone (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der angegebene akzeptable Index nicht g├╝ltig ist (d

h

er verweist auf ein Element au├čerhalb des aktuellen Stapels), andernfalls 0.

[-0, +0, -]

int lua_isnoneornil (lua_State *L, int index);

Gibt 1 zur├╝ck, wenn der angegebene akzeptable Index nicht g├╝ltig ist (d

h

auf ein Element au├čerhalb des aktuellen Stapels verweist) oder wenn der Wert an diesem Index null ist, andernfalls 0.

[-0, +0, -]

int lua_isnumber (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index eine Zahl oder ein String ist, der in eine Zahl umgewandelt werden kann, andernfalls 0.

[-0, +0, -]

int lua_iststring (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index ein String oder eine Zahl ist (die immer in einen String umwandelbar ist), andernfalls 0.

[-0, +0, -]

int lua_istable (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index eine Tabelle ist, andernfalls 0.

[-0, +0, -]

int lua_isthread (lua_State *L, int-Index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index ein Thread ist, andernfalls 0.

[-0, +0, -]

int lua_isuserdata(lua_State *L, int index);

Gibt 1 zur├╝ck, wenn der Wert am gegebenen akzeptablen Index ein Benutzerdatenwert ist (entweder voll oder leicht), andernfalls 0.

[-0, +0, e]

int lua_lessthan(lua_State *L, int index1, int index2);

Gibt 1 zur├╝ck, wenn der Wert am akzeptablen Index index1 kleiner als der Wert am akzeptablen Index index2 ist, gem├Ą├č der Semantik des Operators Lua < (d

h

kann Metamethoden aufrufen)

Gibt andernfalls 0 zur├╝ck

Gibt auch 0 zur├╝ck, wenn einer der Indizes ung├╝ltig ist

[-0, +1, -]

int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname);

L├Ądt einen Lua-Chunk

Wenn keine Fehler vorliegen, schiebt lua_load den kompilierten Chunk als Lua-Funktion oben auf den Stapel

Andernfalls wird eine Fehlermeldung ausgegeben

Die R├╝ckgabewerte von lua_load sind:

0: keine Fehler;

keine Fehler; LUA_ERRSYNTAX : Syntaxfehler w├Ąhrend der Vorkompilierung;

Syntaxfehler w├Ąhrend der Vorkompilierung; LUA_ERRMEM : Speicherzuordnungsfehler

Diese Funktion l├Ądt nur einen Teil; es f├╝hrt es nicht aus

lua_load erkennt automatisch, ob der Chunk Text oder bin├Ąr ist, und l├Ądt ihn entsprechend (siehe Programm luac )

Die lua_load-Funktion verwendet eine vom Benutzer bereitgestellte Reader-Funktion, um den Chunk zu lesen (siehe lua_Reader )

Das Datenargument ist ein undurchsichtiger Wert, der an die Reader-Funktion ├╝bergeben wird.

Das Chunkname-Argument gibt dem Chunk einen Namen, der f├╝r Fehlermeldungen und Debug-Informationen verwendet wird (siehe ┬ž3.8)

[-0, +0, -]

lua_State *lua_newstate (lua_Alloc f, void *ud);

Erstellt einen neuen, unabh├Ąngigen Staat

Gibt NULL zur├╝ck, wenn der Status nicht erstellt werden kann (aufgrund von Speichermangel)

Das Argument f ist die Zuordnungsfunktion; Lua ├╝bernimmt die gesamte Speicherzuweisung f├╝r diesen Zustand ├╝ber diese Funktion

Das zweite Argument, ud , ist ein undurchsichtiger Zeiger, den Lua bei jedem Aufruf einfach an den Allocator weitergibt.

[-0, +1, m]

void lua_newtable (lua_State *L);

Erstellt eine neue leere Tabelle und schiebt sie auf den Stack

Es ist ├Ąquivalent zu lua_createtable(L, 0, 0).

[-0, +1, m]

lua_State *lua_newthread (lua_State *L);

Erstellt einen neuen Thread, schiebt ihn auf den Stapel und gibt einen Zeiger auf einen lua_State zur├╝ck, der diesen neuen Thread darstellt

Der von dieser Funktion zur├╝ckgegebene neue Zustand teilt alle globalen Objekte (z

B

Tabellen) mit dem urspr├╝nglichen Zustand, hat aber einen unabh├Ąngigen Ausf├╝hrungsstapel

Es gibt keine explizite Funktion zum Schlie├čen oder Zerst├Âren eines Threads

Threads unterliegen wie alle Lua-Objekte der Garbage Collection

[-0, +1, m]

void *lua_newuserdata(lua_State *L, size_t size);

Diese Funktion weist einen neuen Speicherblock mit der angegebenen Gr├Â├če zu, schiebt neue vollst├Ąndige Benutzerdaten mit der Blockadresse auf den Stapel und gibt diese Adresse zur├╝ck

Benutzerdaten repr├Ąsentieren C-Werte in Lua

Vollst├Ąndige Benutzerdaten repr├Ąsentieren einen Speicherblock

Es ist ein Objekt (wie eine Tabelle): Sie m├╝ssen es erstellen, es kann seine eigene Metatabelle haben, und Sie k├Ânnen erkennen, wann es erfasst wird

Vollst├Ąndige Benutzerdaten sind nur sich selbst gleich (unter roher Gleichheit)

Wenn Lua vollst├Ąndige Benutzerdaten mit einer gc-Metamethode sammelt, ruft Lua die Metamethode auf und markiert die Benutzerdaten als abgeschlossen

Wenn diese Benutzerdaten erneut gesammelt werden, gibt Lua den entsprechenden Speicher frei

[-1, +(2|0), e]

int lua_next (lua_State *L, int-Index);

Holt einen Schl├╝ssel aus dem Stapel und schiebt ein Schl├╝ssel-Wert-Paar aus der Tabelle am angegebenen Index (das “n├Ąchste” Paar nach dem angegebenen Schl├╝ssel)

Wenn es keine weiteren Elemente in der Tabelle gibt, gibt lua_next 0 zur├╝ck (und pusht nichts)

Eine typische Traversierung sieht so aus:

/* Tabelle ist im Stack bei Index ‘t’ */ lua_pushnil(L); /* erster Schl├╝ssel */ while (lua_next(L, t) != 0) { /* verwendet ‘Schl├╝ssel’ (bei Index -2) und ‘Wert’ (bei Index -1) */ printf(“%s – % s.”, lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); /* entfernt ‘Wert’; beh├Ąlt ‘Schl├╝ssel’ f├╝r die n├Ąchste Iteration */ lua_pop(L, 1); }

Rufen Sie beim Durchlaufen einer Tabelle lua_tolstring nicht direkt f├╝r einen Schl├╝ssel auf, es sei denn, Sie wissen, dass der Schl├╝ssel tats├Ąchlich ein String ist

Denken Sie daran, dass lua_tolstring den Wert am angegebenen Index ├Ąndert; das verwirrt den n├Ąchsten Aufruf von lua_next.

typedef double lua_Number;

Die Art der Zahlen in Lua

Standardm├Ą├čig ist es doppelt, aber das kann in luaconf.h ge├Ąndert werden.

Durch die Konfigurationsdatei k├Ânnen Sie Lua so ├Ąndern, dass es mit einem anderen Typ f├╝r Zahlen arbeitet (z

B

Float oder Long)

[-0, +0, – ]

size_t lua_objlen(lua_State *L, int index);

Gibt die “L├Ąnge” des Werts am gegebenen akzeptablen Index zur├╝ck: f├╝r Zeichenfolgen ist dies die Zeichenfolgenl├Ąnge; bei Tabellen ist dies das Ergebnis des L├Ąngenoperators (‘ # ‘); f├╝r Benutzerdaten ist dies die Gr├Â├če des f├╝r die Benutzerdaten zugewiesenen Speicherblocks; f├╝r andere Werte ist es 0.

[-(nargs + 1), +(nresults|1), -]

int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

Ruft eine Funktion im gesch├╝tzten Modus auf

Sowohl nargs als auch nresults haben dieselbe Bedeutung wie in lua_call

Wenn w├Ąhrend des Aufrufs keine Fehler auftreten, verh├Ąlt sich lua_pcall genauso wie lua_call

Wenn es jedoch einen Fehler gibt, f├Ąngt lua_pcall ihn ab, schiebt einen einzelnen Wert auf den Stack (die Fehlermeldung) und gibt einen Fehlercode zur├╝ck

Wie lua_call entfernt lua_pcall immer die Funktion und ihre Argumente vom Stack.

Wenn errfunc 0 ist, dann ist die auf dem Stack zur├╝ckgegebene Fehlermeldung genau die urspr├╝ngliche Fehlermeldung

Andernfalls ist errfunc der Stapelindex einer Fehlerbehandlungsfunktion

(In der aktuellen Implementierung kann dieser Index kein Pseudo-Index sein.) Im Falle von Laufzeitfehlern wird diese Funktion mit der Fehlermeldung aufgerufen und ihr R├╝ckgabewert ist die Nachricht, die von lua_pcall auf dem Stack zur├╝ckgegeben wird Die Fehlerbehandlungsfunktion wird verwendet, um der Fehlermeldung weitere Debug-Informationen hinzuzuf├╝gen, z

B

ein Stack-Traceback

Solche Informationen k├Ânnen nach der R├╝ckkehr von lua_pcall nicht gesammelt werden, da sich der Stack bis dahin entladen hat

Die Funktion lua_pcall gibt im Erfolgsfall 0 oder einen der folgenden Fehlercodes (in lua.h definiert) zur├╝ck:

LUA_ERRRUN : ein Laufzeitfehler.

ein Laufzeitfehler

LUA_ERRMEM : Speicherzuweisungsfehler

F├╝r solche Fehler ruft Lua die Fehlerbehandlungsfunktion nicht auf

Speicherzuweisungsfehler

F├╝r solche Fehler ruft Lua die Fehlerbehandlungsfunktion nicht auf

LUA_ERRERR : Fehler beim Ausf├╝hren der Fehlerbehandlungsfunktion.

[-n, +0, -]

void lua_pop(lua_State *L, int n);

Nimmt n Elemente aus dem Stapel.

[-0, +1, -]

void lua_pushboolean(lua_State *L, int b);

Schiebt einen booleschen Wert mit dem Wert b auf den Stack.

[-n, +1, m]

void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n);

Schiebt einen neuen C-Verschluss auf den Stapel

Wenn eine C-Funktion erstellt wird, ist es m├Âglich, ihr einige Werte zuzuordnen, wodurch ein C-Abschluss erstellt wird (siehe ┬ž3.4); diese Werte sind dann f├╝r die Funktion bei jedem Aufruf zug├Ąnglich

Um Werte mit einer C-Funktion zu verkn├╝pfen, sollten diese Werte zuerst auf den Stapel geschoben werden (wenn mehrere Werte vorhanden sind, wird der erste Wert zuerst geschoben)

Dann wird lua_pushcclosure aufgerufen, um die C-Funktion zu erstellen und auf den Stapel zu schieben, wobei das Argument n angibt, wie viele Werte der Funktion zugeordnet werden sollen

lua_pushclosure holt diese Werte auch vom Stack

Der maximale Wert f├╝r n ist 255.

[-0, +1, m]

void lua_pushcfunction (lua_State *L, lua_CFunction f);

Schiebt eine C-Funktion auf den Stack

Diese Funktion empf├Ąngt einen Zeiger auf eine C-Funktion und schiebt einen Lua-Wert vom Typ function auf den Stack, der beim Aufruf die entsprechende C-Funktion aufruft

Jede Funktion, die in Lua registriert werden soll, muss dem richtigen Protokoll folgen, um ihre Parameter zu empfangen und zur├╝ckzugeben seine Ergebnisse (siehe lua_CFunction ).

lua_pushcfunction ist als Makro definiert:

#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)

[-0, +1, m]

const char *lua_pushfstring (lua_State *L, const char *fmt,. ..);

Legt eine formatierte Zeichenfolge auf den Stapel und gibt einen Zeiger auf diese Zeichenfolge zur├╝ck

Sie ├Ąhnelt der C-Funktion sprintf , weist jedoch einige wichtige Unterschiede auf:

Sie m├╝ssen dem Ergebnis keinen Speicherplatz zuweisen: Das Ergebnis ist ein Lua-String, und Lua k├╝mmert sich um die Speicherzuweisung (und die Freigabe durch Garbage Collection)

Die Konvertierungsspezifizierer sind ziemlich eingeschr├Ąnkt

Es gibt keine Flags, Breiten oder Genauigkeiten

Die Konvertierungsbezeichner k├Ânnen nur ‘ %% ‘ (f├╝gt ein ‘ % ÔÇőÔÇő’ in die Zeichenfolge ein), ‘ %s ‘ (f├╝gt eine nullterminierte Zeichenfolge ohne Gr├Â├čenbeschr├Ąnkung ein), ‘ %f ‘ (f├╝gt eine lua_Number ) ein, ‘ %p ‘ (f├╝gt einen Zeiger als Hexadezimalzahl ein), ‘ %d ‘ (f├╝gt ein int ein) und ‘ %c ‘ (f├╝gt ein int als Zeichen ein).

[-0, +1, -]

void lua_pushinteger(lua_State *L, lua_Integer n);

Schiebt eine Zahl mit dem Wert n auf den Stack.

[-0, +1, -]

void lua_pushlightuserdata(lua_State *L, void *p);

Schiebt leichte Benutzerdaten auf den Stack

Benutzerdaten repr├Ąsentieren C-Werte in Lua

Ein leichtes Benutzerdatum repr├Ąsentiert einen Zeiger

Es ist ein Wert (wie eine Zahl): Sie erstellen es nicht, es hat keine individuelle Metatabelle und es wird nicht gesammelt (da es nie erstellt wurde)

Leichte Benutzerdaten sind gleich “beliebigen” leichten Benutzerdaten mit der gleichen C-Adresse.

[-0, +1, m]

void lua_pushliteral(lua_State *L, const char *s);

Dieses Makro entspricht lua_pushlstring , kann aber nur verwendet werden, wenn s eine Literalzeichenfolge ist

In diesen F├Ąllen liefert es automatisch die Zeichenfolgenl├Ąnge.

[-0, +1, m]

void lua_pushlstring(lua_State *L, const char *s, size_t len);

Schiebt den String, auf den s zeigt, mit der Gr├Â├če len auf den Stack

Lua erstellt (oder verwendet) eine interne Kopie der angegebenen Zeichenfolge, sodass der Speicher bei s sofort nach der R├╝ckkehr der Funktion freigegeben oder wiederverwendet werden kann

Der String kann eingebettete Nullen enthalten.

[-0, +1, -]

void lua_pushnil(lua_State *L);

Schiebt einen Nullwert auf den Stack.

[-0, +1, -]

void lua_pushnumber (lua_State *L, lua_Number n);

Schiebt eine Zahl mit dem Wert n auf den Stack.

[-0, +1, m]

void lua_pushstring(lua_State *L, const char *s);

Schiebt den nullterminierten String, auf den s zeigt, auf den Stack

Lua erstellt (oder verwendet) eine interne Kopie der angegebenen Zeichenfolge, sodass der Speicher bei s sofort nach der R├╝ckkehr der Funktion freigegeben oder wiederverwendet werden kann

Die Zeichenfolge darf keine eingebetteten Nullen enthalten; es wird angenommen, dass es bei der ersten Null endet

[-0, +1, -]

int lua_pushthread(lua_State *L);

Schiebt den durch L repr├Ąsentierten Thread auf den Stack

Gibt 1 zur├╝ck, wenn dieser Thread der Hauptthread seines Zustands ist

[-0, +1, -]

void lua_pushvalue (lua_State *L, int index);

Schiebt eine Kopie des Elements am angegebenen g├╝ltigen Index auf den Stapel.

[-0, +1, m]

const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);

├äquivalent zu lua_pushfstring , au├čer dass es eine va_list anstelle einer variablen Anzahl von Argumenten erh├Ąlt.

[-0, +0, -]

int lua_rawequal(lua_State *L, int index1, int index2);

Gibt 1 zur├╝ck, wenn die beiden Werte in den akzeptablen Indizes index1 und index2 primitiv gleich sind (d

h

ohne Aufruf von Metamethoden)

Gibt andernfalls 0 zur├╝ck

Gibt auch 0 zur├╝ck, wenn einer der Indizes ung├╝ltig ist

[-1, +1, -]

void lua_rawget(lua_State *L, int index);

Ähnlich wie lua_gettable , führt aber einen Rohzugriff durch (d

h

ohne Metamethoden)

[-0, +1, -]

void lua_rawgeti (lua_State *L, int index, int n);

Legt den Wert t[n] auf den Stack, wobei t der Wert am gegebenen g├╝ltigen Index ist

Der Zugriff ist roh; das hei├čt, es ruft keine Metamethoden auf.

[-2, +0, m]

void lua_rawset(lua_State *L, int index);

Ähnlich wie lua_settable , führt aber eine Rohzuweisung durch (d

h

ohne Metamethoden)

[-1, +0, m]

void lua_rawseti(lua_State *L, int index, int n);

Führt das Äquivalent von t[n] = v aus, wobei t der Wert am gegebenen gültigen Index und v der Wert ganz oben auf dem Stapel ist

Diese Funktion holt den Wert aus dem Stapel

Die Aufgabe ist roh; das hei├čt, es ruft keine Metamethoden auf

typedef const char * (*lua_Reader) (lua_State *L, void *data, size_t *size);

Die von lua_load verwendete Lesefunktion

Jedes Mal, wenn ein weiteres St├╝ck des Chunks ben├Âtigt wird, ruft lua_load den Reader auf und ├╝bergibt seinen Datenparameter

Der Leser muss einen Zeiger auf einen Speicherblock mit einem neuen Teil des Chunks zur├╝ckgeben und die Gr├Â├če auf die Blockgr├Â├če setzen

Der Block muss bestehen bleiben, bis die Reader-Funktion erneut aufgerufen wird

Um das Ende des Chunks zu signalisieren, muss der Reader NULL zur├╝ckgeben oder die Gr├Â├če auf Null setzen

Die Reader-Funktion kann Teile jeder Gr├Â├če gr├Â├čer als Null zur├╝ckgeben.

[-0, +0, e]

void lua_register (lua_State *L, const char *name, lua_CFunction f);

Legt die C-Funktion f als neuen Wert des globalen Namens fest

Es ist als Makro definiert:

#define lua_register(L,n,f) \ (lua_pushcfunction(L, f), lua_setglobal(L, n))

[-1, +0, -]

void lua_remove(lua_State *L, int index);

Entfernt das Element am angegebenen g├╝ltigen Index und verschiebt die Elemente ├╝ber diesem Index nach unten, um die L├╝cke zu f├╝llen

Kann nicht mit einem Pseudo-Index aufgerufen werden, da ein Pseudo-Index keine tats├Ąchliche Stapelposition ist.

[-1, +0, -]

void lua_replace(lua_State *L, int index);

Verschiebt das oberste Element an die angegebene Position (und f├╝gt es ein), ohne ein Element zu verschieben (und ersetzt daher den Wert an der angegebenen Position).

[-?, +?, -]

int lua_resume(lua_State *L, int narg);

Startet und setzt eine Coroutine in einem bestimmten Thread fort.

Um eine Coroutine zu starten, erstellen Sie zuerst einen neuen Thread (siehe lua_newthread ); dann schieben Sie die Hauptfunktion plus alle Argumente auf ihren Stack; dann rufen Sie lua_resume auf, wobei narg die Anzahl der Argumente ist

Dieser Aufruf kehrt zur├╝ck, wenn die Coroutine ihre Ausf├╝hrung anh├Ąlt oder beendet

Wenn es zur├╝ckkehrt, enth├Ąlt der Stapel alle an lua_yield ├╝bergebenen Werte oder alle von der body-Funktion zur├╝ckgegebenen Werte

lua_resume gibt LUA_YIELD zur├╝ck, wenn die Coroutine nachgibt, 0, wenn die Coroutine ihre Ausf├╝hrung ohne Fehler beendet, oder einen Fehlercode im Falle von Fehlern (siehe lua_pcall )

Im Fehlerfall wird der Stack nicht entladen, sodass Sie die Debug-API dar├╝ber verwenden k├Ânnen

Die Fehlermeldung befindet sich ganz oben auf dem Stapel

Um eine Coroutine neu zu starten, legen Sie nur die Werte, die als Ergebnisse von yield ├╝bergeben werden sollen, auf ihren Stack und rufen dann lua_resume.

[-0, +0, -] auf

void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);

Ändert die Zuordnungsfunktion eines gegebenen Zustands zu f mit Benutzerdaten ud.

[-1, +0, -]

int lua_setfenv (lua_State *L, int-Index);

Holt eine Tabelle aus dem Stapel und legt sie als neue Umgebung f├╝r den Wert am angegebenen Index fest

Wenn der Wert am gegebenen Index weder eine Funktion noch ein Thread noch Benutzerdaten ist, gibt lua_setfenv 0 zur├╝ck

Andernfalls gibt es 1 zur├╝ck.

[-1, +0, e]

void lua_setfield (lua_State *L, int index, const char *k);

Macht das Äquivalent zu t[k] = v , wobei t der Wert am angegebenen gültigen Index und v der Wert ganz oben auf dem Stapel ist

Diese Funktion holt den Wert aus dem Stapel

Wie in Lua kann diese Funktion eine Metamethode f├╝r das “newindex”-Ereignis ausl├Âsen (siehe ┬ž2.8).

[-1, +0, e]

void lua_setglobal(lua_State *L, const char *name);

Holt einen Wert aus dem Stack und legt ihn als neuen Wert des globalen Namens fest

Es ist als Makro definiert:

#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)

[-1, +0, -]

int lua_setmetatable (lua_State *L, int index);

Holt eine Tabelle aus dem Stapel und legt sie als neue Metatabelle f├╝r den Wert am angegebenen akzeptablen Index fest

[-2, +0, e]

void lua_settable(lua_State *L, int index);

Hat das Äquivalent zu t[k] = v , wobei t der Wert am angegebenen gültigen Index ist, v der Wert ganz oben auf dem Stapel ist und k der Wert direkt unter der Spitze ist

Diese Funktion gibt beide Schl├╝ssel aus und den Wert aus dem Stack

Wie in Lua kann diese Funktion eine Metamethode f├╝r das “newindex”-Ereignis ausl├Âsen (siehe ┬ž2.8).

[-?, +?, -]

void lua_settop(lua_State *L, int index);

Akzeptiert jeden akzeptablen Index oder 0 und setzt den Stack-Top auf diesen Index

Wenn die neue Spitze gr├Â├čer als die alte ist, werden die neuen Elemente mit Null gef├╝llt

Wenn index 0 ist, werden alle Stack-Elemente entfernt

typedef struct lua_State lua_State;

Undurchsichtige Struktur, die den gesamten Zustand eines Lua-Interpreters beibeh├Ąlt

Die Lua-Bibliothek ist vollst├Ąndig ablaufinvariant: Sie hat keine globalen Variablen

Alle Informationen ├╝ber einen Zustand werden in dieser Struktur gespeichert

Ein Zeiger auf diesen Zustand muss als erstes Argument an jede Funktion in der Bibliothek ├╝bergeben werden, au├čer an lua_newstate , das einen Lua-Zustand von Grund auf neu erstellt

[-0, +0 , -]

int lua_status (lua_State *L);

Gibt den Status des Threads L zur├╝ck

Der Status kann 0 f├╝r einen normalen Thread sein, ein Fehlercode, wenn der Thread seine Ausf├╝hrung mit einem Fehler beendet hat, oder LUA_YIELD, wenn der Thread ausgesetzt ist

[-0, +0, -]

int lua_toboolean (lua_State *L, int-Index);

Konvertiert den Lua-Wert am angegebenen akzeptablen Index in einen booleschen C-Wert (0 oder 1)

Wie alle Tests in Lua gibt lua_toboolean 1 f├╝r jeden Lua-Wert zur├╝ck, der sich von false und nil unterscheidet; andernfalls gibt es 0 zur├╝ck

Es gibt auch 0 zur├╝ck, wenn es mit einem ung├╝ltigen Index aufgerufen wird

(Wenn Sie nur tats├Ąchliche boolesche Werte akzeptieren m├Âchten, verwenden Sie lua_isboolean, um den Typ des Werts zu testen.) [-0, +0, -]

lua_CFunction lua_tocfunction (lua_State *L, int index);

Konvertiert einen Wert am angegebenen akzeptablen Index in eine C-Funktion

Dieser Wert muss eine C-Funktion sein; andernfalls wird NULL.

[-0, +0, -] zur├╝ckgegeben

lua_Integer lua_tointeger (lua_State *L, int-Index);

Konvertiert den Lua-Wert am angegebenen akzeptablen Index in den vorzeichenbehafteten ganzzahligen Typ lua_Integer

Der Lua-Wert muss eine Zahl oder ein in eine Zahl umwandelbarer String sein (siehe ┬ž2.2.1); andernfalls gibt lua_tointeger 0 zur├╝ck.

Wenn die Zahl keine ganze Zahl ist, wird sie auf eine nicht spezifizierte Weise abgeschnitten.

[-0, +0, m]

const char *lua_tolstring (lua_State *L, int index, size_t *len);

Konvertiert den Lua-Wert am angegebenen akzeptablen Index in einen C-String

Wenn len nicht NULL ist, wird auch *len mit der Zeichenfolgenl├Ąnge festgelegt

Der Lua-Wert muss ein String oder eine Zahl sein; andernfalls gibt die Funktion NULL zur├╝ck

Wenn der Wert eine Zahl ist, dann ├Ąndert lua_tolstring auch den tats├Ąchlichen Wert im Stack in einen String

(Diese ├änderung bringt lua_next durcheinander, wenn lua_tolstring w├Ąhrend einer Tabellendurchquerung auf Schl├╝ssel angewendet wird.) lua_tolstring gibt einen vollst├Ąndig ausgerichteten Zeiger auf eine Zeichenfolge innerhalb des Lua-Zustands zur├╝ck

Dieser String hat immer eine Null (‘ \0 ‘) nach seinem letzten Zeichen (wie in C), kann aber andere Nullen in seinem K├Ârper enthalten

Da Lua ├╝ber Garbage Collection verf├╝gt, gibt es keine Garantie daf├╝r, dass der von lua_tolstring zur├╝ckgegebene Zeiger g├╝ltig ist, nachdem der entsprechende Wert aus dem Stack entfernt wurde.

[-0, +0, -]

lua_Number lua_tonumber (lua_State *L, int index);

Konvertiert den Lua-Wert am angegebenen akzeptablen Index in den C-Typ lua_Number (siehe lua_Number )

Der Lua-Wert muss eine Zahl oder ein in eine Zahl umwandelbarer String sein (siehe ┬ž2.2.1); andernfalls gibt lua_tonumber 0.

[-0, +0, -] zur├╝ck

const void *lua_topointer(lua_State *L, int index);

Konvertiert den Wert am angegebenen akzeptablen Index in einen generischen C-Zeiger ( void* )

Der Wert kann Benutzerdaten, eine Tabelle, ein Thread oder eine Funktion sein; andernfalls gibt lua_topointer NULL zur├╝ck

Unterschiedliche Objekte geben unterschiedliche Zeiger

Es gibt keine M├Âglichkeit, den Zeiger wieder auf seinen urspr├╝nglichen Wert umzuwandeln

Normalerweise wird diese Funktion nur f├╝r Debug-Informationen verwendet

[-0, +0, m]

const char *lua_tostring (lua_State *L, int index);

├äquivalent zu lua_tolstring mit len ÔÇőÔÇőgleich NULL.

[-0, +0, -]

lua_State *lua_tothread (lua_State *L, int-Index);

Konvertiert den Wert am angegebenen akzeptablen Index in einen Lua-Thread (dargestellt als lua_State* )

Dieser Wert muss ein Thread sein; andernfalls gibt die Funktion NULL.

[-0, +0, -] zur├╝ck

void *lua_touserdata(lua_State *L, int index);

Wenn der Wert am angegebenen akzeptablen Index vollst├Ąndige Benutzerdaten sind, wird seine Blockadresse zur├╝ckgegeben

Wenn es sich bei dem Wert um leichte Benutzerdaten handelt, wird sein Zeiger zur├╝ckgegeben

Andernfalls wird NULL.

[-0, +0, -] zur├╝ckgegeben

int lua_type (lua_State *L, int-Index);

Gibt den Typ des Werts im angegebenen akzeptablen Index oder LUA_TNONE f├╝r einen ung├╝ltigen Index (d

h

einen Index auf eine “leere” Stapelposition) zur├╝ck

Die von lua_type zur├╝ckgegebenen Typen werden durch die folgenden in lua.h definierten Konstanten codiert: LUA_TNIL , LUA_TNUMBER , LUA_TBOOLEAN , LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA , LUA_TTHREAD und LUA_TLIGHTUSERDATA.

[-0, +0, -]

const char *lua_typename (lua_State *L, int tp);

Gibt den Namen des durch den Wert tp codierten Typs zur├╝ck, der einer der von lua_type.

typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); zur├╝ckgegebenen Werte sein muss

Der Typ der Writer-Funktion, die von lua_dump verwendet wird

Jedes Mal, wenn es einen weiteren Chunk erzeugt, ruft lua_dump den Writer auf und ├╝bergibt den zu schreibenden Puffer ( p ), seine Gr├Â├če ( sz ) und den an lua_dump gelieferten Datenparameter

Der Writer gibt einen Fehlercode zur├╝ck: 0 bedeutet nein Fehler; jeder andere Wert bedeutet einen Fehler und verhindert, dass lua_dump den Writer erneut aufruft.

[-?, +?, -]

void lua_xmove(lua_State *from, lua_State *to, int n);

Werte zwischen verschiedenen Threads desselben globalen Zustands austauschen.

Diese Funktion holt n Werte aus dem Stack von und schiebt sie auf den Stack bis.

[-?, +?, -]

int lua_yield (lua_State *L, int nresults);

Ergibt eine Coroutine.

Diese Funktion sollte nur wie folgt als R├╝ckgabeausdruck einer C-Funktion aufgerufen werden:

gib lua_yield (L, nresults) zur├╝ck;

Wenn eine C-Funktion lua_yield auf diese Weise aufruft, unterbricht die laufende Coroutine ihre Ausf├╝hrung, und der Aufruf von lua_resume, der diese Coroutine gestartet hat, kehrt zur├╝ck

Der Parameter nresults ist die Anzahl der Werte aus dem Stapel, die als Ergebnisse an lua_resume ├╝bergeben werden

Lua hat keine eingebauten Debugging-M├Âglichkeiten

Stattdessen bietet es eine spezielle Schnittstelle mittels Funktionen und Hooks

Diese Schnittstelle erm├Âglicht die Konstruktion verschiedener Arten von Debuggern, Profilern und anderen Tools, die “Insiderinformationen” vom Interpreter ben├Âtigen

typedef struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) */ const char *was; /* (S) */ const char *Quelle; /* (S) */ int aktuelle Zeile; /* (l) */ int nups; /* (u) Anzahl der Aufw├Ąrtswerte */ int linedefined; /* (S) */ int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* privater Teil */ andere Felder } lua_Debug;

Eine Struktur, die verwendet wird, um verschiedene Informationen ├╝ber eine aktive Funktion zu transportieren

lua_getstack f├╝llt nur den privaten Teil dieser Struktur zur sp├Ąteren Verwendung

Um die anderen Felder von lua_Debug mit n├╝tzlichen Informationen zu f├╝llen, rufen Sie lua_getinfo auf

Die Felder von lua_Debug haben folgende Bedeutung:

source : Wenn die Funktion in einem String definiert wurde, dann ist source dieser String

Wenn die Funktion in einer Datei definiert wurde, beginnt die Quelle mit einem ‘ @ ‘, gefolgt vom Dateinamen

Wenn die Funktion in einer Zeichenfolge definiert wurde, dann ist diese Zeichenfolge

Wenn die Funktion in einer Datei definiert wurde, beginnt sie mit einem ‘ ‘ gefolgt vom Dateinamen

short_src : eine “druckbare” Version von source , zur Verwendung in Fehlermeldungen.

eine “druckbare” Version von , zur Verwendung in Fehlermeldungen

linedefined : die Zeilennummer, wo die Definition der Funktion beginnt.

die Zeilennummer, wo die Definition der Funktion beginnt

lastlinedefined : die Zeilennummer, wo die Definition der Funktion endet.

die Zeilennummer, wo die Definition der Funktion endet

was: die Zeichenfolge ÔÇ×LuaÔÇť, wenn die Funktion eine Lua-Funktion ist, ÔÇ×CÔÇť, wenn es eine C-Funktion ist, ÔÇ×mainÔÇť, wenn es der Hauptteil eines Chunks ist, und ÔÇ×tailÔÇť, wenn es eine Funktion war, die a ausgef├╝hrt hat Endruf

Im letzteren Fall hat Lua keine weiteren Informationen ├╝ber die Funktion

Die Zeichenfolge, ob die Funktion eine Lua-Funktion ist, ob es sich um eine C-Funktion handelt, ob es sich um den Hauptteil eines Chunks handelt und ob es sich um eine Funktion handelt, die dies getan hat ein Tail-Call

Im letzteren Fall hat Lua keine weiteren Informationen ├╝ber die Funktion

currentline : die aktuelle Zeile, in der die angegebene Funktion ausgef├╝hrt wird

Wenn keine Zeileninformationen verf├╝gbar sind, wird die aktuelle Zeile auf -1 gesetzt.

die aktuelle Zeile, in der die angegebene Funktion ausgef├╝hrt wird

Wenn keine Leitungsinformationen verf├╝gbar sind, wird auf -1 gesetzt

name : ein vern├╝nftiger Name f├╝r die gegebene Funktion

Da Funktionen in Lua erstklassige Werte sind, haben sie keinen festen Namen: Einige Funktionen k├Ânnen der Wert mehrerer globaler Variablen sein, w├Ąhrend andere nur in einem Tabellenfeld gespeichert werden k├Ânnen

Die Funktion lua_getinfo pr├╝ft, wie die Funktion aufgerufen wurde, um einen passenden Namen zu finden

Wenn es keinen Namen finden kann, wird name auf NULL gesetzt

Ein vern├╝nftiger Name f├╝r die angegebene Funktion

Da Funktionen in Lua erstklassige Werte sind, haben sie keinen festen Namen: Einige Funktionen k├Ânnen der Wert mehrerer globaler Variablen sein, w├Ąhrend andere nur in einem Tabellenfeld gespeichert werden k├Ânnen

Die Funktion pr├╝ft, wie die Funktion aufgerufen wurde, um einen passenden Namen zu finden

Wenn es keinen Namen finden kann, wird es auf gesetzt

namewhat : erkl├Ąrt das Namensfeld

Der Wert von namewhat kann ÔÇ×globalÔÇť , ÔÇ×localÔÇť , ÔÇ×methodÔÇť , ÔÇ×fieldÔÇť , ÔÇ×upvalueÔÇť oder ÔÇ×ÔÇť (der leere String) sein, je nachdem, wie die Funktion aufgerufen wurde

(Lua verwendet die leere Zeichenfolge, wenn keine andere Option zutrifft.)

erkl├Ąrt das Feld

Der Wert von kann , , , , oder (die leere Zeichenfolge) sein, je nachdem, wie die Funktion aufgerufen wurde

(Lua verwendet den leeren String, wenn keine andere Option zutrifft.) nups : die Anzahl der Aufw├Ąrtswerte der Funktion.

[-0, +0, -]

lua_Hook lua_gethook (lua_State *L);

Gibt die aktuelle Hook-Funktion zur├╝ck.

[-0, +0, -]

int lua_gethookcount(lua_State *L);

Gibt die aktuelle Hook-Anzahl zur├╝ck

[-0, +0, -]

int lua_gethookmask(lua_State *L);

Gibt die aktuelle Hook-Maske zur├╝ck

[-(0|1), +(0|1|2), m]

int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);

Gibt Informationen ├╝ber eine bestimmte Funktion oder einen Funktionsaufruf zur├╝ck

Um Informationen ├╝ber einen Funktionsaufruf zu erhalten, muss der Parameter ar ein g├╝ltiger Aktivierungsdatensatz sein, der durch einen vorherigen Aufruf von lua_getstack gef├╝llt oder als Argument an einen Hook ├╝bergeben wurde (siehe lua_Hook )

Um Informationen ├╝ber eine Funktion zu erhalten, schiebt man sie auf den Stack und beginnt den What-String mit dem Zeichen ‘ > ‘

(In diesem Fall legt lua_getinfo die Funktion ganz oben auf dem Stapel ab.) Um beispielsweise zu wissen, in welcher Zeile eine Funktion f definiert wurde, k├Ânnen Sie den folgenden Code schreiben:

lua_Debug ar; lua_getfield(L, LUA_GLOBALSINDEX, “f”); /* globales ‘f’ holen */ lua_getinfo(L, “>S”, &ar); printf(“%d

“, ar.linedefined);

Jedes Zeichen in der Zeichenfolge, das einige Felder der Struktur ausw├Ąhlt, muss ausgef├╝llt werden, oder ein Wert, der auf den Stapel geschoben werden soll:

‘ n ‘: f├╝llt das Feld name und namewhat aus ;

f├╝llt das Feld aus und ; ‘ S ‘: f├╝llt die Felder source , short_src , linedefined , lastlinedefined und what ; aus

f├╝llt die Felder , , , , und aus; ‘l’: f├╝llt das Feld aktuelle Zeile aus ;

f├╝llt das Feld aus ; ‘ u ‘: f├╝llt das Feld nups ;

f├╝llt das Feld aus ; ‘ f ‘: legt die Funktion, die auf der angegebenen Ebene l├Ąuft, auf den Stack;

schiebt die Funktion, die auf der angegebenen Ebene ausgef├╝hrt wird, auf den Stapel; ‘ L ‘: legt eine Tabelle auf den Stapel, deren Indizes die Nummern der Zeilen sind, die f├╝r die Funktion g├╝ltig sind

(Eine g├╝ltige Zeile ist eine Zeile mit zugeh├Ârigem Code, dh eine Zeile, in der Sie einen Haltepunkt setzen k├Ânnen

Ung├╝ltige Zeilen umfassen leere Zeilen und Kommentare.) Diese Funktion gibt im Fehlerfall 0 zur├╝ck (z

B

eine ung├╝ltige Option in what ).

[-0, +(0|1), -]

const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);

Ruft Informationen ├╝ber eine lokale Variable eines bestimmten Aktivierungsdatensatzes ab

Der Parameter ar muss ein g├╝ltiger Aktivierungsdatensatz sein, der durch einen vorherigen Aufruf von lua_getstack gef├╝llt oder als Argument an einen Hook ├╝bergeben wurde (siehe lua_Hook )

Der Index n w├Ąhlt aus, welche lokale Variable untersucht werden soll (1 ist der erste Parameter oder die erste aktive lokale Variable usw

bis zur letzten aktiven lokalen Variablen)

lua_getlocal schiebt den Wert der Variablen auf den Stack und gibt ihren Namen zur├╝ck

Variablennamen, die mit ‘ ( ‘ (offene Klammern) beginnen, stellen interne Variablen dar (Schleifensteuerungsvariablen, Tempor├Ąre und lokale C-Funktionen)

Gibt NULL zur├╝ck (und schiebt nichts), wenn Der Index ist gr├Â├čer als die Anzahl der aktiven lokalen Variablen f├╝llt Teile einer lua_Debug-Struktur mit einer Identifikation des Aktivierungsdatensatzes der Funktion, die auf einer bestimmten Ebene ausgef├╝hrt wird

Ebene 0 ist die aktuell ausgef├╝hrte Funktion, w├Ąhrend Ebene n+1 die Funktion ist, die Ebene n aufgerufen hat

Wenn keine Fehler vorliegen, wenn es mit einem Level aufgerufen wird, das gr├Â├čer als die Stapeltiefe ist, gibt es 0 zur├╝ck.

[-0, +(0|1), -].const char *lua_getupvalue (lua_State *L, int funcindex, int n); der Aufw├Ąrtswert einer Closure (Bei Lua-Funktionen sind Aufw├Ąrtswerte die externen lokalen Variablen, die die Funktion n verwendet, und die folglich in seiner Closure enthalten sind.) lua_getupvalue erh├Ąlt den Index n eines Aufw├Ąrtswerts, schiebt den Wert des Aufw├Ąrtswerts

Debugging Practice: Using Print Statements Update

Video ansehen

Neue Informationen zum Thema debug print

debug print Ähnliche Bilder im Thema

 Update New Debugging Practice: Using Print Statements
Debugging Practice: Using Print Statements Update

java – Difference between logger.info and logger.debug … New

26/2/2010┬á┬Ě If you want to print the value of a variable at any given point, you might call Logger.debug. This combination of a configurable logging level and logging statements within your program allow you full control over how your application will log its activity.

+ mehr hier sehen

Read more

Ich schlage vor, dass Sie sich den Artikel “Kurze Einf├╝hrung in log4j” ansehen

Es enth├Ąlt eine kurze Erl├Ąuterung der Protokollierungsebenen und demonstriert, wie sie in der Praxis verwendet werden k├Ânnen

Die Grundidee von Log-Leveln ist, dass Sie je nach Situation konfigurieren k├Ânnen m├Âchten, wie viele Details die Logs enthalten

Wenn Sie beispielsweise versuchen, ein Problem zu beheben, m├Âchten Sie, dass die Protokolle sehr ausf├╝hrlich sind

In der Produktion m├Âchten Sie m├Âglicherweise nur Warnungen und Fehler sehen

Die Protokollebene f├╝r jede Komponente Ihres Systems wird normalerweise durch einen Parameter in einer Konfigurationsdatei gesteuert, sodass sie leicht ge├Ąndert werden kann

Ihr Code w├╝rde verschiedene Protokollierungsanweisungen mit unterschiedlichen Ebenen enthalten

Wenn Sie auf eine Ausnahme reagieren, k├Ânnen Sie Logger.error aufrufen

Wenn Sie den Wert einer Variablen zu einem bestimmten Zeitpunkt drucken m├Âchten, k├Ânnen Sie Logger.debug aufrufen

Diese Kombination aus einer konfigurierbaren Protokollierungsebene und Protokollierungsanweisungen in Ihrem Programm erm├Âglicht Ihnen die vollst├Ąndige Kontrolle dar├╝ber, wie Ihre Anwendung ihre Aktivit├Ąten protokolliert

Zumindest im Fall von log4j lautet die Reihenfolge der Protokollierungsebenen:

DEBUG < INFO < WARN < FEHLER < FATAL

Hier ist ein kurzes Beispiel aus diesem Artikel, das zeigt, wie Protokollebenen funktionieren.

Excel | Macros | Debug Print Excel New Update

Video unten ansehen

Weitere Informationen zum Thema debug print

debug print Sie k├Ânnen die sch├Ânen Bilder im Thema sehen

 Update New Excel | Macros | Debug Print Excel
Excel | Macros | Debug Print Excel Update

Weitere Informationen zum Thema anzeigen debug print

Updating

Dies ist eine Suche zum Thema debug print

Updating

Ende des Themas debug print

Articles compiled by Tratamientorosacea.com. See more articles in category: DIGITAL MARKETING

Related Videos

Leave a Comment