Julia Language
@goto i @label
Szukaj…
Składnia
- @goto label
- Etykieta @label
Uwagi
Nadużywanie lub niewłaściwe stosowanie zaawansowanego przepływu sterowania utrudnia odczyt kodu. @goto
lub jego odpowiedniki w innych językach, jeśli są niewłaściwie używane, prowadzą do nieczytelnego kodu spaghetti.
Podobnie jak języki takie jak C, nie można przeskakiwać między funkcjami w Julii. Oznacza to również, że @goto
nie jest możliwe na najwyższym poziomie; będzie działać tylko w ramach funkcji. Ponadto nie można przeskoczyć z funkcji wewnętrznej do jej funkcji zewnętrznej lub z funkcji zewnętrznej do funkcji wewnętrznej.
Sprawdzanie poprawności danych wejściowych
Chociaż nie są tradycyjnie uważane za pętle, makra @goto
i @label
mogą być używane do bardziej zaawansowanego przepływu sterowania. Jednym z przypadków użycia jest awaria jednej części, która powinna doprowadzić do ponownej próby całej funkcji, często przydatnej w sprawdzaniu poprawności danych wejściowych:
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
Jednak ten przypadek użycia jest często bardziej przejrzysty przy użyciu rekurencji:
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
Chociaż oba przykłady robią to samo, drugi jest łatwiejszy do zrozumienia. Jednak pierwszy z nich jest bardziej wydajny (ponieważ pozwala uniknąć połączenia rekurencyjnego). W większości przypadków koszt połączenia nie ma znaczenia; ale w ograniczonych sytuacjach pierwsza forma jest dopuszczalna.
Błąd czyszczenia
W językach takich jak C często używana jest instrukcja @goto
aby zapewnić, że funkcja wyczyści niezbędne zasoby, nawet w przypadku błędu. Jest to mniej ważne w Julii, ponieważ wyjątki i try
- w finally
często używane są bloki.
Możliwe jest jednak, że kod Julii będzie się łączył z kodem C i interfejsami API C, więc czasami funkcje muszą być napisane tak jak kod C. Poniższy przykład został opracowany, ale pokazuje typowy przypadek użycia. Kod Julia wywoła Libc.malloc
aby przydzielić trochę pamięci (symuluje to wywołanie C API). Jeśli nie wszystkie alokacje się powiodą, funkcja powinna uwolnić dotychczasowe zasoby; w przeciwnym razie przydzielona pamięć zostanie zwrócona.
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