Julia Language
@goto y @label
Buscar..
Sintaxis
- etiqueta @goto
- etiqueta @label
Observaciones
El uso excesivo o inadecuado del flujo de control avanzado hace que el código sea difícil de leer. @goto
o sus equivalentes en otros idiomas, cuando se usan incorrectamente, conducen a un código de espagueti ilegible.
Similar a lenguajes como C, uno no puede saltar entre funciones en Julia. Esto también significa que @goto
no es posible en el nivel superior; Sólo funcionará dentro de una función. Además, uno no puede saltar de una función interna a su función externa, o de una función externa a una función interna.
Validación de entrada
Aunque tradicionalmente no se consideran los bucles, las macros @goto
y @label
se pueden usar para un flujo de control más avanzado. Un caso de uso es cuando el fallo de una parte debería llevar a reintentar una función completa, a menudo útil en la validación de entrada:
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
Sin embargo, este caso de uso es a menudo más claro usando recursión:
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
Aunque ambos ejemplos hacen lo mismo, el segundo es más fácil de entender. Sin embargo, el primero es más eficaz (porque evita la llamada recursiva). En la mayoría de los casos, el costo de la llamada no importa; pero en situaciones limitadas, la primera forma es aceptable.
Error de limpieza
En lenguajes como C, la instrucción @goto
se usa a menudo para garantizar que una función limpie los recursos necesarios, incluso en el caso de un error. Esto es menos importante en Julia, porque las excepciones y try
- finally
bloques se utilizan a menudo en su lugar.
Sin embargo, es posible que el código Julia se interconecte con el código C y las API de C, por lo que a veces las funciones aún deben escribirse como código C. El siguiente ejemplo está diseñado, pero demuestra un caso de uso común. El código de Julia llamará a Libc.malloc
para asignar algo de memoria (esto simula una llamada de la API C). Si no todas las asignaciones tienen éxito, entonces la función debería liberar los recursos obtenidos hasta el momento; de lo contrario, se devuelve la memoria asignada.
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