Ricerca…


Sintassi

  • Etichetta @goto
  • etichetta @label

Osservazioni

L'uso eccessivo o inappropriato del flusso di controllo avanzato rende il codice difficile da leggere. @goto o i suoi equivalenti in altre lingue, se usati in modo improprio, portano a codice spaghetti illeggibile.

Simile alle lingue come C, non si può saltare tra le funzioni di Julia. Ciò significa anche che @goto non è possibile al livello più alto; Funzionerà solo all'interno di una funzione. Inoltre, non si può saltare da una funzione interiore alla sua funzione esterna, o da una funzione esterna a una funzione interiore.

Convalida dell'input

Sebbene non siano tradizionalmente considerati loop, i macro @goto e @label possono essere utilizzati per un flusso di controllo più avanzato. Un caso d'uso è quando il fallimento di una parte dovrebbe portare al nuovo tentativo di un'intera funzione, spesso utile nella convalida dell'input:

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

Tuttavia, questo caso d'uso è spesso più chiaro usando la ricorsione:

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

Sebbene entrambi gli esempi facciano la stessa cosa, il secondo è più facile da capire. Tuttavia, il primo è più performante (perché evita la chiamata ricorsiva). Nella maggior parte dei casi, il costo della chiamata non ha importanza; ma in situazioni limitate, la prima forma è accettabile.

Pulizia errore

In linguaggi come C, l'istruzione @goto viene spesso utilizzata per garantire che una funzione pulisca le risorse necessarie, anche in caso di errore. Questo è meno importante in Julia, perché le eccezioni e i blocchi try - finally vengono spesso utilizzati.

Tuttavia, è possibile che il codice Julia si interfaccia con il codice C e le API C, quindi a volte le funzioni devono ancora essere scritte come il codice C. L'esempio seguente è ideato, ma dimostra un caso d'uso comune. Il codice Julia chiamerà Libc.malloc per allocare memoria (simula una chiamata API C). Se non tutte le allocazioni sono riuscite, allora la funzione dovrebbe liberare le risorse ottenute finora; in caso contrario, viene restituita la memoria allocata.

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow