Julia Language
@gotoと@label
サーチ…
構文
- @gotoラベル
- @ラベルラベル
備考
高度な制御フローの過度の使用や不適切な使用は、コードを読みにくくします。他の言語の@goto
またはそれに相当するものは、不適切に使用すると、スパゲッティコードが判読できなくなります。
Cのような言語と同様に、Juliaの関数間でジャンプすることはできません。これはトップレベルで@goto
ができないことを意味します。関数内でのみ機能します。さらに、内部関数から外部関数にジャンプすることも、外部関数から内部関数にジャンプすることもできません。
入力検証
伝統的に考えられるループではありませんが、 @goto
@label
マクロと@label
マクロは、より高度な制御フローに使用できます。 1つのユースケースは、1つの部分の障害が関数全体の再試行につながる必要がある場合です。入力検証に役立つことがよくあります。
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
ただし、このユースケースは再帰を使用するとより明確になることがよくあります。
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
どちらの例も同じことをしていますが、2番目の例は理解しやすいです。しかし、最初の方がパフォーマンスが良いです(再帰呼び出しを避けるため)。ほとんどの場合、コールのコストは問題になりません。限られた状況では、最初の形式は受け入れられます。
エラークリーンアップ
Cのような言語では、 @goto
文は、エラーが発生した場合でも関数が必要なリソースを確実にクリーンアップするためによく使われます。これはジュリアではあまり重要ではありません。なぜなら例外やtry
- finally
ブロックがよく使われるからです。
しかし、JuliaコードはCコードやC APIとのインタフェースが可能であるため、関数はCコードのように記述する必要があることがあります。以下の例は考案されていますが、一般的な使用例を示しています。 JuliaコードはLibc.malloc
を呼び出してメモリを割り当てます(これはC API呼び出しをシミュレートします)。すべての割り当てが成功したわけではない場合、関数はそれまでに取得したリソースを解放する必要があります。それ以外の場合は、割り当てられたメモリが返されます。
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