Zoeken…


Syntaxis

  • @goto label
  • @label label

Opmerkingen

Overmatig of oneigenlijk gebruik van geavanceerde besturingsstroom maakt code moeilijk te lezen. @goto of zijn equivalenten in andere talen leidt bij onjuist gebruik tot onleesbare spaghetti-code.

Vergelijkbaar met talen zoals C, kan men niet schakelen tussen functies in Julia. Dit betekent ook dat @goto niet mogelijk is op het hoogste niveau; het werkt alleen binnen een functie. Verder kan men niet van een innerlijke functie naar zijn uiterlijke functie springen, of van een uiterlijke functie naar een innerlijke functie.

Invoervalidatie

Hoewel niet traditioneel beschouwd als lussen, kunnen de macro's @goto en @label worden gebruikt voor een meer geavanceerde besturingsstroom. Eén use case is wanneer het falen van een onderdeel moet leiden tot het opnieuw proberen van een hele functie, vaak handig bij inputvalidatie:

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

Deze use case is echter vaak duidelijker met behulp van recursie:

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

Hoewel beide voorbeelden hetzelfde doen, is het tweede gemakkelijker te begrijpen. De eerste is echter meer performant (omdat deze de recursieve oproep vermijdt). In de meeste gevallen doen de kosten van de oproep er niet toe; maar in beperkte situaties is de eerste vorm acceptabel.

Fout bij opschonen

In talen zoals C wordt de instructie @goto vaak gebruikt om ervoor te zorgen dat een functie de benodigde bronnen opruimt, zelfs in het geval van een fout. Dit is minder belangrijk in Julia, omdat uitzonderingen en try - finally worden in plaats daarvan vaak blokken gebruikt.

Het is echter mogelijk voor Julia-code om te communiceren met C-code en C-API's, en daarom moeten functies soms nog worden geschreven zoals C-code. Het onderstaande voorbeeld is gekunsteld, maar demonstreert een veelvoorkomend gebruik. De Julia-code roept Libc.malloc aan om wat geheugen toe te wijzen (dit simuleert een C API-aanroep). Als niet alle toewijzingen slagen, moet de functie de tot nu toe verkregen middelen vrijmaken; anders wordt het toegewezen geheugen geretourneerd.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow