Julia: 関数と配列についての諸注意

今後の授業では,関数と配列が非常に重要ですので,これらについて幾つか注意を述べておきます.

関数:キーワード引数

関数を定義する際,キーワード引数は,引数の指定を位置ではなく名前でおこないます.また,デフォルトの値を設定しておきたいとき(例えば,最大反復回数や許容誤差)にも便利です.

julia> function f(x;y=1)
       return x+y
       end
f (generic function with 1 method)

julia> f(2)
3

julia> f(2,y=0.1)
2.1

型を指定することもできます.

julia> function g(x;y::Int64=1)
       return x+y
       end
g (generic function with 1 method)

julia> g(2,y=1)
3

julia> g(2,y=0.1)
ERROR: TypeError: in keyword argument y, expected Int64, got Float64
Stacktrace:
 [1] (::getfield(Main, Symbol("#kw##g")))(::NamedTuple{(:y,),Tuple{Float64}}, ::typeof(g), ::Int64) at ./none:0
 [2] top-level scope at REPL[15]:1

Int64 は 64-bit signed integer type なので,このように小数を代入をしようとするとエラーが起きます.型についての詳細は,公式ドキュメント を参照するとよいでしょう.

また,キーワード引数が二つ以上ある場合,どの順番で指定しても問題ありません.

julia> function h(x;y=1,z=2)
       return x*y+z
       end
h (generic function with 1 method)

julia> h(1,z=3)
4

julia> h(1,z=3,y=2)
5

関数:複数の戻り値の名前付きタプル化

複数の戻り値を持つ関数の定義についてです.たとえば,次のような定義と取り出し方が標準的だと思います.

julia> function f(x,y)
           return x, [x,y], x+y
       end
f (generic function with 1 method)

julia> a = f(2,3)
(2, [2, 3], 5)

julia> a[2]
2-element Array{Int64,1}:
 2
 3

julia> [3]
1-element Array{Int64,1}:
 3

julia> a ,b = f(2,3)
(2, [2, 3], 5)

julia> a
2

julia> b
2-element Array{Int64,1}:
 2
 3

一方で,次のように戻り値のタプルの要素に名前をつけて定義することもできます.

julia> function f(x,y)
           return (p = x, P = [x,y], q = x+y)
       end
f (generic function with 1 method)

julia> x = f(2,3)
(p = 2, P = [2, 3], q = 5)

julia> x[1]
2

julia> x.p
2

julia> x[2]
2-element Array{Int64,1}:
 2
 3

julia> x.P
2-element Array{Int64,1}:
 2
 3

julia> x[3]
5

julia> x.q
5

julia> a,b,c = f(4,5)
(p = 4, P = [4, 5], q = 9)

julia> a
4

julia> b
2-element Array{Int64,1}:
 4
 5

julia> c
9

julia> l, m = f(4,5)
(p = 4, P = [4, 5], q = 9)

julia> l
4

julia> m
2-element Array{Int64,1}:
 4
 5

配列:参照渡し と 値渡し

Juliaでプログラムを書く際,参照渡しに注意が必要です.Juliaはmatlabと同様の感覚でプログラムを書けますが,matlabのデフォルトは値渡しなのでmatlabに慣れている場合は特に注意が必要です.

まず,値渡しの例:

julia> a = 1
1

julia> b = a
1

julia> b +=2
3

julia> a
1

要するに,bの値は変わってもaの値は変わりません.

次に参照渡しの例:

julia> a = [1,2]
2-element Array{Int64,1}:
 1
 2

julia> b = a
2-element Array{Int64,1}:
 1
 2

julia> b[1]=2
 2

julia> b
2-element Array{Int64,1}:
 2
 2

julia> a
2-element Array{Int64,1}:
 2
 2

この場合,参照渡しとなりaの値も変更されます.これを避けたければ例えば

julia> b = a[:]

julia> b = copy(a)

のようにすればよいです.