裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia -- 9(制御構文)

2020年12月25日 | ブログラミング

制御構文

複合式  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

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Julia -- 5(関数) | トップ | Julia -- 10-1(配列) »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事