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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow