制御構文
複合式 begin, ;
begin と end で囲まれた式を,順に実行する。最後の式の評価値が返される。
julia> z = begin
x = 1
y = 2
x + y
end
3
1 行に 1 つの式しか書けないということではない。一行にまとめて書くこともできる。それぞれの式は ';' で区切ればよい。
julia> begin x = 1; y = 2; x + y end
3
'begin' と 'end' で囲む代わりに '( )' で囲んでもよい。
julia> z = (x = 1; y = 2; x + y)
3
もちろん,この場合も行を分けてもよい。
julia> (x = 1;
y = 2;
x + y)
3
条件評価 if-elseif-else, 三項演算子 ?:
julia> function test(x, y)
if x < y
println("x is less than y")
elseif x > y
println("x is greater than y")
else
println("x is equal to y")
end
end
test (generic function with 2 methods)
julia> test(1, 2)
x is less than y
julia> test(2, 1)
x is greater than y
julia> test(1, 1)
x is equal to y
他のプログラム言語とは違うかもしれないが,Julia の if ブロックはローカルスコープを作らないので,if ブロック内で定義された変数はその外でも使える(筆者注:多くの言語経験者は,「当たり前だろう」と思うかも知れないが)。
Julia の if ブロックは,最後に実行された文(式)の値を戻り値とする。
julia> x = 3;
julia> if x > 0
"positive!"
else
"negative..."
end
"positive!"
他の多くのプログラミング言語とは異なり,条件式は true か false いずれかの評価値を持つものでなければならない。
julia> if 1 println("true") end
ERROR: TypeError: non-boolean (Int64) used in boolean context
julia> if true println("true") end
true
2 つ上の例は,三項演算子を用いて書くことができる。
julia> x = 10; x > 0 ? "positive!" : "negative..."
"positive!"
julia> x = -10; x > 0 ? "positive!" : "negative..."
"negative..."
複雑にすることも出来る。
julia> test(x, y) = println(x < y ? "x is less than y" :
x > y ? "x is greater than y" : "x is equal to y")
test (generic function with 2 methods)
julia> test(1, 2)
x is less than y
julia> test(2, 1)
x is greater than y
julia> test(1, 1)
x is equal to y
ショート・サーキット評価 &&, ||, チェイン比較
a && b という論理式で,a が true のときのみ b が評価される。
a || b という論理式で,a が false のときのみ b が評価される。
if end は, && と同じである。
if ! end は, || と同じである。
これにより,if ブロックを書かずに式を記述できる。
julia> function fact(n::Int)
n >= 0 || error("n must be non-negative")
n == 0 && return 1
end
fact (generic function with 1 method)
julia> fact(-3)
ERROR: n must be non-negative
julia> fact(0)
1
julia> fact(5)
120
&&,|| のオペランドは最後のものは何でもよいが,それ以外は true, false を返すものでなくてはならない。
julia> 1 && true
ERROR: TypeError: non-boolean (Int64) used in boolean context
julia> true && (1, 2, 3)
(1, 2, 3)
julia> false && (1, 2, 3)
falseビット論理演算子 &, |
&&, || と違い,ショート・サーキット評価は行われない。全てのビットが評価される。
julia> 0b0101 & 0b1110
0x04
julia> 0b0101 | 0b1110
0x0f
繰り返し評価 while, for
while
julia> i = 1;
julia> while i <= 5
println(i)
global i += 1 # global って,何だろう?
end
1
2
3
4
5
for
for ループの外(後)では i は未定義になる。つまり,i のスコープは for ループ内だけである。
julia> for i = 1:5
println(i)
end
1
2
3
4
5
julia> for i in 1:4
println(i)
end
1
2
3
4
in と ∈
julia> for i in [1, 4, 0]
println(i)
end
1
4
0
julia> for s ∈ ["foo","bar","baz"]
println(s)
end
foo
bar
baz
break によるループからの脱出
julia> i = 1;
julia> while true
println(i)
if i >= 5
break
end
global i += 1
end
1
2
3
4
5
julia> for j = 1:1000
println(j)
if j >= 5
break
end
end
1
2
3
4
5
continue によるループの一部分スキップ
julia> for i = 1:10
if i % 3 != 0
continue
end
println(i)
end
3
6
9
複数の for ループの組み合わせ
julia> for i = 1:2, j = 3:4
println((i, j))
end
(1, 3)
(1, 4)
(2, 3)
(2, 4)
例外処理
ArgumentError
BoundsError
CompositeException
DimensionMismatch
DividError
DomainError
julia> sqrt(-1)
ERROR: DomainError with -1.0:
EOFError
ErrorException
InexactError
InitError
InterruptException
InvalidStateException
KeyError
LoadError
OutOfMemoryError
ReadOnlyMemoryError
RemoteException
MethodError
OverflowError
Meta.ParseError
SystemError
TypeError
UndefRefError
UndefVarError
StringIndexError
ユーザが定義できる例外
julia> struct MyCustomException <: Exception end
throw 関数
throw により,明示的に例外を作ることができる。
julia> f(x) = x>=0 ? exp(-x) : throw(DomainError(x, "argument must be nonnegative"))
f (generic function with 2 methods)
julia> f(1)
0.36787944117144233
julia> f(-1)
ERROR: DomainError with -1:
argument must be nonnegative
julia> typeof(DomainError(nothing)) <: Exception
true
julia> typeof(DomainError) <: Exception
false
julia> throw(UndefVarError(:x))
ERROR: UndefVarError: x not defined
julia> struct MyUndefVarError <: Exception
var::Symbol
end
julia> Base.showerror(io::IO, e::MyUndefVarError) = print(io, e.var, " not defined")
error 関数
error 関数は,正常な制御の流れを遮る ErrorException を生成するために使われる。
julia> fussy_sqrt(x) = x >= 0 ? sqrt(x) : error("negative x not allowed")
fussy_sqrt (generic function with 1 method)
julia> fussy_sqrt(2)
1.4142135623730951
julia> fussy_sqrt(-1)
ERROR: negative x not allowed
try/catch 文
julia> try
sqrt("ten")
catch e
println("You should have entered a numeric value")
end
You should have entered a numeric value
julia> sqrt_second(x) = try
sqrt(x[2])
catch y
if isa(y, DomainError)
sqrt(complex(x[2], 0))
elseif isa(y, BoundsError)
sqrt(x)
end
end
sqrt_second (generic function with 1 method)
julia> sqrt_second([1 4])
2.0
julia> sqrt_second([1 -4])
0.0 + 2.0im
julia> sqrt_second(9)
3.0
julia> sqrt_second(-9)
ERROR: DomainError with -9.0:
finally 句
finally 句には例外処理の後始末を書く。
f = open("file")
try
# operate on file f
finally
close(f)
end
タスク(共同関数) yieldto
未
※コメント投稿者のブログIDはブログ作成者のみに通知されます