Julia Language
@goto und @label
Suche…
Syntax
- @goto label
- @label label
Bemerkungen
Übermäßiger Gebrauch oder unangemessene Verwendung des erweiterten Kontrollflusses macht den Code schwer lesbar. @goto
oder seine Entsprechungen in anderen Sprachen führen bei unsachgemäßer Verwendung zu unlesbarem Spaghetti-Code.
Ähnlich wie Sprachen wie C kann man in Julia nicht zwischen Funktionen wechseln. Dies bedeutet auch, dass @goto
auf der obersten Ebene nicht möglich ist. es funktioniert nur innerhalb einer Funktion. Außerdem kann man nicht von einer inneren Funktion zu ihrer äußeren Funktion oder von einer äußeren Funktion zu einer inneren Funktion springen.
Eingabeüberprüfung
@label
Makros @goto
und @label
können zwar @label
nicht als Schleifen betrachtet werden, können jedoch für einen erweiterten Steuerungsfluss verwendet werden. Ein Anwendungsfall liegt vor, wenn der Ausfall eines Teils dazu führen sollte, dass eine gesamte Funktion erneut versucht wird. Dies ist häufig bei der Validierung von Eingaben hilfreich:
function getsequence()
local a, b
@label start
print("Input an integer: ")
try
a = parse(Int, readline())
catch
println("Sorry, that's not an integer.")
@goto start
end
print("Input a decimal: ")
try
b = parse(Float64, readline())
catch
println("Sorry, that doesn't look numeric.")
@goto start
end
a, b
end
Dieser Anwendungsfall wird jedoch häufig mit Rekursion klarer:
function getsequence()
local a, b
print("Input an integer: ")
try
a = parse(Int, readline())
catch
println("Sorry, that's not an integer.")
return getsequence()
end
print("Input a decimal: ")
try
b = parse(Float64, readline())
catch
println("Sorry, that doesn't look numeric.")
return getsequence()
end
a, b
end
Obwohl beide Beispiele dasselbe tun, ist das zweite verständlicher. Der erste ist jedoch performanter (weil er den rekursiven Aufruf vermeidet). In den meisten Fällen spielen die Kosten des Anrufs keine Rolle. In begrenzten Situationen ist die erste Form jedoch akzeptabel.
Fehler beim Bereinigen
In Sprachen wie C wird die @goto
Anweisung häufig verwendet, um sicherzustellen, dass eine Funktion die erforderlichen Ressourcen auch im Fehlerfall aufräumt. Dies ist bei Julia weniger wichtig, da stattdessen oft Ausnahmen und try
finally
Blöcke verwendet werden.
Es ist jedoch möglich, dass Julia-Code eine Schnittstelle zu C-Code und C-APIs herstellt, sodass Funktionen manchmal noch wie C-Code geschrieben werden müssen. Das nachfolgende Beispiel ist zwar entwickelt, zeigt aber einen allgemeinen Anwendungsfall. Der Julia-Code ruft Libc.malloc
auf, um Speicherplatz zuzuordnen (dies simuliert einen C-API-Aufruf). Wenn nicht alle Zuordnungen erfolgreich sind, sollte die Funktion die bisher erhaltenen Ressourcen freigeben. Andernfalls wird der zugewiesene Speicher zurückgegeben.
using Base.Libc
function allocate_some_memory()
mem1 = malloc(100)
mem1 == C_NULL && @goto fail
mem2 = malloc(200)
mem2 == C_NULL && @goto fail
mem3 = malloc(300)
mem3 == C_NULL && @goto fail
return mem1, mem2, mem3
@label fail
free(mem1)
free(mem2)
free(mem3)
end