Julia入門 条件分岐・複文・ループ

前回の記事に引き続き、Juliaの入門というか、一通りの機能を触りながら記事にしていきたいと思う。

ちなみにJuliaは型(Type)システムがコンセプトのなかで非常に重要なのだけど、そこそこハードな内容になりそうなので、あとで記事にまとめるまではあまり使用せずに説明していく。*1

nullbyte.hatenablog.com

ちなみに対象としているバージョンは

$ julia --version
julia version 0.3.8

です。

if文

if i % 15 == 0
    println("fizzbuzz")
elseif i % 5 == 0
    println("buzz")
elseif i % 3 == 0
    println("fizz")
else
    println(i)
end

if文は前回紹介した通り、上記のような形になる。

ちなみに、&& (AND演算)や || (OR 演算)を用いて、以下のような書き方もできる。
条件分岐のよりJuliaらしい書き方としてよく使われるようである。
この書き方の方がより簡潔になる場合は、採用するとよいと思う。

julia> a = 1
1

julia> a == a && print("OK")
OK
julia> a != a || print("NG")
NG

FizzBuzzをこの方法で書き直すと、以下のようにcontinueをつけないといけない。
若干イマイチ。素直にif ~ elseifでつなげた方がベターかと思う。

for i in 1:15
    i % 15 == 0 && (println("fizzbuzz"); continue)
    i % 5 == 0 && (println("buzz"); continue)
    i % 3 == 0 && (println("fizz"); continue)
    println(i)
end

ちなみに&&の右辺が複文になる場合、カッコがないとセミコロンから先が左辺の結果とは無関係に評価されるので注意。

複文(Compound Expression)

上記のcondition && expr .....のようなコードがより複雑になってくると、一行で書くのが厳しくなってくると思う。
そんな時は以下のbegin ~ end構文を利用するとよい。

true && begin
            do_something()
            do_otherthing()
            do_yetotherthing()
        end

以下のように=でつなげると、beginブロックで最後に評価された式の結果が、1行目のtotalに代入される。

julia> total = begin
                   price = 2980
                   tax = 1.08
                   price * tax
               end
3218.4

ちなみにbeginはスコープを作らない。つまり、beginの内側で定義した変数は外側でも使える(外側に影響をあたえる)ので注意。*2

ブロック内に変数の影響範囲を留めたい場合は、localつきで宣言すれば良い。

julia> begin
           val = "dirty data"
           local localval = val
       end
"dirty data"

julia> val
"dirty data"

julia> localval
ERROR: localval not defined

ループ

ループにはforとwhileの2種類がある 。

julia> for i in 1:5
           print(i, ", ")
       end
1, 2, 3, 4, 5, 

julia> i = 1     # MUST!
1

julia> while i <= 5
           print(i, "->")
           i += 1
       end
1->2->3->4->5->

上のコードでi = 1とwhile文の前で定義している事に注意。そうしないと、while文でnot definedのエラーが発生する。

また、for文についてはC言語チックな"for (int i = 0; i < 10; i++) { }" という構文はない。
あくまでも上記のようにIteratableなオブジェクト(配列など)の中身を走査しながら変数に代入していく形になる。
*3

また、以下のように、二つの変数を同時にfor文に指定することができる。
この場合、同時に進むのではなく、全部の組み合わせが実行される。
ここは他の言語であまりみない動きだと思うので、注意。

julia> for i = 1:3, j = 1:3
         print(i, " - ", j,  "\n")
       end
1 - 1
1 - 2
1 - 3
2 - 1
2 - 2
2 - 3
3 - 1
3 - 2
3 - 3

また、for i in 1:5の代わりにfor i = 1:5 というふうに=で書けて、同じ意味だということもおさえておこう。

2つの配列を同時に走査したければ、以下のようにzip関数を使えばできる。

julia> for (i, j) in zip(1:3, 6:9)
         print(i, " - ", j,  "\n")
       end
1 - 6
2 - 7
3 - 8

参考リンク

以下のオフィシャルのDocumentationを参考にした。

続きはまた明日・・・。

*1: ちょっとしたプログラムなら、面倒な型宣言を気にせずコーディングできるのは、Juliaのとっつきやすさでもある

*2:function, while, for, try, catch, finally, let, type はレキシカルスコープを作る

*3:例えば上記の"1:5"の部分は、Rangeオブジェクトという、1から5までを表す配列状のオブジェクトになっている。