Julia Language
@goto och @ label
Sök…
Syntax
- @goto etikett
- @ etikett
Anmärkningar
Överanvändning eller olämplig användning av avancerat kontrollflöde gör kod svårläst. @goto
eller dess ekvivalenter på andra språk leder när de används på fel sätt till oläslig spaghettikod.
I likhet med språk som C kan man inte hoppa mellan funktioner i Julia. Detta innebär också att @goto
inte är möjligt på toppnivå; det fungerar bara inom en funktion. Dessutom kan man inte hoppa från en inre funktion till dess yttre funktion, eller från en yttre funktion till en inre funktion.
Ingångsvalidering
Även om inte traditionellt betraktade slingor, kan @goto
@label
@goto
och @label
användas för mer avancerat kontrollflöde. Ett användningsfall är när misslyckandet i en del bör leda till att en hel funktion försöks på nytt, ofta användbar vid validering av inmatning:
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
Men detta fall är ofta tydligare med rekursion:
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
Även om båda exemplen gör samma sak, är det andra lättare att förstå. Den första är emellertid mer performant (eftersom den undviker det rekursiva samtalet). I de flesta fall spelar ingen kostnad för samtalet; men i begränsade situationer är den första formen acceptabel.
Felrensning
På språk som C används @goto
uttalandet ofta för att säkerställa att en funktion rensar upp nödvändiga resurser, även i händelse av ett fel. Detta är mindre viktigt i Julia, för undantag och try
- finally
block ofta istället.
Det är emellertid möjligt för Julia-koden att gränssnitta med C-kod och C-API: er, och ibland behöver funktioner fortfarande skrivas som C-kod. Nedanstående exempel är motsatt, men visar ett fall med vanligt bruk. Julia-koden kommer att ringa Libc.malloc
att allokera lite minne (detta simulerar ett C API-samtal). Om inte alla tilldelningar lyckas, bör funktionen frigöra de resurser som hittills erhållits; annars returneras det tilldelade minnet.
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