Julia特有の構文メモ2
ライブラリ
Juliaの関数は大きく3つに分けられる.
- コアベースの関数
- 標準ライブラリの関数
- 外部ライブラリの関数
コアベースの関数
Core.
関数
Core.ifelse
判定文が真なら1つ目、偽なら2つ目の引数を返す.
julia> Core.ifelse('a' < 'A', 'a', 'A') 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase) julia> Core.ifelse(10/3==10÷3, "same", "not same") "not same" #juliaのif判定はboolean型しか受け付けない. julia> Core.ifelse(1, "one", "not one") ERROR: TypeError: non-boolean (Int64) used in boolean context Stacktrace: [1] top-level scope at REPL[4]:1
Core.applicable
引数が関数に適用可能か判定する.
julia> myfunc(a::Int64,b::Int64)=a*b myfunc (generic function with 1 method) #引数が一つだけでもダメ julia> applicable(myfunc,2) false #片方がFloatでもダメ julia> applicable(myfunc,2,2.5) false #2つが両方IntならOK julia> applicable(myfunc,2,2) true
Core.tuple
タプルを作成する(関数がTupleではなくtuple).
julia> stationery=tuple("Pencil","Eraser","Ruler") ("Pencil", "Eraser", "Ruler") julia> typeof(stationery) Tuple{String,String,String}
参照渡しについて.
変数の代入は=
で普通に値を渡すだけ.
b
の値を更新してもa
は影響を受けない.
値が格納される参照先(アドレス)が別々だから.
julia> a = 2 2 julia> b = a 2 julia> b = 3 3 julia> a 2
一方でコレクションは参照渡しなので、 代入した後で更新すると、元のも更新される.
julia> arr_a = [1,2,3] 3-element Array{Int64,1}: 1 2 3 julia> arr_b = arr_a 3-element Array{Int64,1}: 1 2 3 julia> arr_b[2]=20 20 julia> arr_a 3-element Array{Int64,1}: 1 20 3
Base.
関数
Base.copy
浅いコピーcopy
と深いコピーdeepcopy
がある.
参照渡しでないコピーなので、値を更新しても互いに影響しない.
julia> ary_a = [1,2,3] 3-element Array{Int64,1}: 1 2 3 julia> ary_cp = copy(ary_a) 3-element Array{Int64,1}: 1 2 3 julia> ary_dpcp = deepcopy(ary_a) 3-element Array{Int64,1}: 1 2 3 julia> ary_a[2] = 20 20 julia> ary_cp 3-element Array{Int64,1}: 1 2 3 julia> ary_dpcp 3-element Array{Int64,1}: 1 2 3
Base.pointer
配列や文字列のアドレスを出力する.
julia> pointer(ary_a) Ptr{Int64} @0x0000000109e47a10
要素が配列になっている深い配列を考える.
浅いコピーではary_a
の更新に伴って値が変わっている.
julia> ary_a = [[1,2,3],[4,5,6]] 2-element Array{Array{Int64,1},1}: [1, 2, 3] [4, 5, 6] julia> ary_shallow = copy(ary_a) 2-element Array{Array{Int64,1},1}: [1, 2, 3] [4, 5, 6] julia> ary_deep = deepcopy(ary_a) 2-element Array{Array{Int64,1},1}: [1, 2, 3] [4, 5, 6] julia> ary_a[2][2] = 50 50 julia> ary_shallow 2-element Array{Array{Int64,1},1}: [1, 2, 3] [4, 50, 6] julia> ary_deep 2-element Array{Array{Int64,1},1}: [1, 2, 3] [4, 5, 6]
アドレスを見てみると、外枠は違うように見えるが、
julia> pointer(ary_a) Ptr{Array{Int64,1}} @0x000000010a56d7f0 julia> pointer(ary_shallow) Ptr{Array{Int64,1}} @0x0000000109b7b290 julia> pointer(ary_deep) Ptr{Array{Int64,1}} @0x000000010a0a59d0
その要素は、浅いコピーでは元配列と同じ場所に格納されているらしい.
julia> pointer(ary_a[2]) Ptr{Int64} @0x00000001099c5a90 julia> pointer(ary_shallow[2]) Ptr{Int64} @0x00000001099c5a90 julia> pointer(ary_deep[2]) Ptr{Int64} @0x00000001099a2f90
Base.
やCore.
は.
の前を省略できるが、関数によって出来るものと出来ないものがある.
標準ライブラリの関数
Juliaインストール時からすでに用意されている関数.
使う際にはusing
で関数名を宣言する必要がある.
Dates.
関数
julia> Dates.now() ERROR: UndefVarError: Dates not defined Stacktrace: [1] top-level scope at REPL[43]:1 julia> using Dates julia> Dates.now() 2019-10-25T20:51:38.306
Dates.
を省略してもいい.
julia> now() 2019-10-25T20:54:06.016
now()
関数はDateTime型、Data()
関数はDate型を返す.
year()
関数は年を取得する.
dayofweek()
関数は曜日の値、dayname()
関数は曜日の名前を返す.
julia> typeof(now()) DateTime julia> Date(now()) 2019-10-25 julia> year(now()) 2019 julia> year(Date("2019-10-25")) 2019 julia> dayofweek(now()) 5 julia> dayname(now()) "Friday"
Day()
は日、Hour()
は時間を取得する.
それぞれDay
型、Hour
型.
julia> Day(now()) 25 days julia> Hour(now()) 21 hours
足したり引いたり、計算もできる.
julia> Day(now() + Hour(3)) 26 days julia> Date("2019-10-25") + Day(1000) 2022-07-21
型が違う場合
#`==`は計算結果が同じならOK. julia> Hour(1) == Minute(45) + Minute(15) true #`===`は型が同じでないとダメ. julia> Hour(1) === Minute(45) + Minute(15) false
外部ライブラリの関数
JSONを例に.
using JSON #JSON形式にシリアライズするための辞書を用意する. julia> stationery=Dict("Pencil"=>80,"Eraser"=>50,"Ruler"=>100) Dict{String,Int64} with 3 entries: "Ruler" => 100 "Eraser" => 50 "Pencil" => 80 julia> JSON.print(stationery) {"Ruler":100,"Eraser":50,"Pencil":80} #インデントの指定.4は4文字分ということ. julia> JSON.print(stationery,4) { "Ruler": 100, "Eraser": 50, "Pencil": 80 }
julia> stationery_json = JSON.json(stationery) "{\"Ruler\":100,\"Eraser\":50,\"Pencil\":80}"
JSON形式のデータをパース.
julia> stationery_parse = JSON.parse(stationery_json) Dict{String,Any} with 3 entries: "Ruler" => 100 "Eraser" => 50 "Pencil" => 80 julia> println(stationery_parse) Dict{String,Any}("Ruler" => 100,"Eraser" => 50,"Pencil" => 80) #元々の辞書. julia> println(stationery) Dict("Ruler" => 100,"Eraser" => 50,"Pencil" => 80)