Julia Language
@goto en @label
Zoeken…
Syntaxis
- @goto label
- @label label
Opmerkingen
Overmatig of oneigenlijk gebruik van geavanceerde besturingsstroom maakt code moeilijk te lezen. @goto
of zijn equivalenten in andere talen leidt bij onjuist gebruik tot onleesbare spaghetti-code.
Vergelijkbaar met talen zoals C, kan men niet schakelen tussen functies in Julia. Dit betekent ook dat @goto
niet mogelijk is op het hoogste niveau; het werkt alleen binnen een functie. Verder kan men niet van een innerlijke functie naar zijn uiterlijke functie springen, of van een uiterlijke functie naar een innerlijke functie.
Invoervalidatie
Hoewel niet traditioneel beschouwd als lussen, kunnen de macro's @goto
en @label
worden gebruikt voor een meer geavanceerde besturingsstroom. Eén use case is wanneer het falen van een onderdeel moet leiden tot het opnieuw proberen van een hele functie, vaak handig bij inputvalidatie:
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
Deze use case is echter vaak duidelijker met behulp van recursie:
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
Hoewel beide voorbeelden hetzelfde doen, is het tweede gemakkelijker te begrijpen. De eerste is echter meer performant (omdat deze de recursieve oproep vermijdt). In de meeste gevallen doen de kosten van de oproep er niet toe; maar in beperkte situaties is de eerste vorm acceptabel.
Fout bij opschonen
In talen zoals C wordt de instructie @goto
vaak gebruikt om ervoor te zorgen dat een functie de benodigde bronnen opruimt, zelfs in het geval van een fout. Dit is minder belangrijk in Julia, omdat uitzonderingen en try
- finally
worden in plaats daarvan vaak blokken gebruikt.
Het is echter mogelijk voor Julia-code om te communiceren met C-code en C-API's, en daarom moeten functies soms nog worden geschreven zoals C-code. Het onderstaande voorbeeld is gekunsteld, maar demonstreert een veelvoorkomend gebruik. De Julia-code roept Libc.malloc
aan om wat geheugen toe te wijzen (dit simuleert een C API-aanroep). Als niet alle toewijzingen slagen, moet de functie de tot nu toe verkregen middelen vrijmaken; anders wordt het toegewezen geheugen geretourneerd.
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