「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。目下、データ分析・語学に力点を置いています。

MENU

Juliaを基礎からゆっくりと(その03/X)

 \mathrm{R}\mathrm{Python}\mathrm{C}言語関係など覚えたいもの、覚えるべきものはたくさんある一方で、注目が集まっているから、やってみたい。ということでプログラミング言語としての\mathrm{Julia}を学んでいく。

2. Juliaの言語機能

2.4 型

 \mathrm{Julia}の型システムは

  • 動的に型付けできるが型の注釈をコードに付与できる:\mathrm{Julia}は動的型付け(実行時まで値の型が決められていない)に基づくが、必要に応じて型の注釈をコードに付与できる。型注釈を行う必要は必ずしも無く、コードの可読性を上げたい場合や意図的なコードの最適化、多重ディスパッチを用いたい場合などに用いる。
  • 多重ディスパッチで動的にメソッド呼び出しができる:引数の数や型が異なるが同一の名前で定義された複数の関数に対して、実行時に型に応じて適切な関数が実行される仕組み

点が特徴的である。\mathrm{Julia}は一般的なオブジェクト指向プログラミング言語とは異なり、オブジェクトに関数を所属させることはできず、型の継承も存在しない。

2.4.1 型の宣言

 型を明示的に宣言することは必須ではない。たとえば設計段階で型の仕様が決まっている際に想定通りの動作をするかをチェックするために意図的に宣言するなどの用途がある。

### 型の指定: (変数)::(型)
function add_typed(x::Int, y::Int)
    x + y
end
2.4.2 型の親子関係

 \mathrm{Julia}の型システムでは親子関係が存在し、全体で型をノードとするグラフを構成する。

2.4.3 Nothing型

 \mathrm{Nothing}型は「何もない」ことを表す型である。

2.4.4 複合型

 複数の名前付きフィールドをまとめて扱うことのできる型を複合型という。複合型は\mathrm{struct}で定義する。\mathrm{Julia}では型の継承はできない。複合型の各値をフィールドと呼び、型注釈を付与することが可能である。フィールドの値にはドット演算子でアクセスできる。

#=
複合体:C言語でのクラスに相当する
class Point{
    Int x;
    Int y;

    public Float32 distance(){
        return sqrt(this.x^2+ this.y^2)
    }
}

p = new.Point(2,3)
p.distance()
=#

### juliaでの複合体:上記のクラスと同等
struct Point
    x::Int # この各値をフィールドと呼ぶ
    y::Int
end

function distance(p::Point)
    sqrt(p.x^2 + p.y^2)
end

#######
p = Point(2,3)

println(distance(p))

#######
println(p.x)
println(p.y)

# 新しいコンストラクタの定義
Point(x) = Point(x,3)

p = Point(1)
println(p)

# 基本的にはフィールドはimmutableなので変更できない
try
    p.x = 3
catch
    println("フィールドはimmutableで値を変更できません")
end

########
# 値の変更を許したければ、mutable struct ...で定義する
mutable struct Point2
    x::Int
    y::Int
end

p = Point2(3,4)

println(p.x)

p.x = 5

println(p.x)
2.4.5 Union型

 \mathrm{Union}型は複数の型の和集合を表す型である。不用意に作成すると、異常動作を助長しプログラム設計に問題を内在させることになるため、過度な利用は控えた方がよい。よく使われれるのは、\mathrm{Union}\{\mathrm{T, Nothing}\}(\mathrm{T}\mathrm{Int}などの数値型)といった形態である。

2.4.6 パラメトリック

 他の言語でジェネリクスやテンプレートと呼ばれるものである。フィールドの型を引数として指定することができる型である。

# パラメトリック型
mutable struct Point3{T}
    x::T
    y::T
end

p = Point3(2,3)
q = Point3(2.5, 3.2)

println(p)
println(q)

function distance(p::Point3{T}) where T
    sqrt(p.x^2 + p.y^2)
end

println(distance(p))
println(distance(q))

### 型に応じて異なる動作をさせたいとき、if文で分岐させることが可能
# 多重ディスパッチでは、より具体的な型を優先する
function distance(p::Point3{T}) where T
    if T==Int
        # Int型のときの動作
    elseif T==Float64
        # Float64型のときの動作
    else
        # それ以外のときの動作:たとえばエラーを返すことすると…
        throw("Error")
    end
end
2.4.7 パラメトリック型の階層関係

 型には階層関係がある。たとえば\mathrm{Int}型には



\begin{aligned}
\mathrm{Int}\ <\ \mathrm{Signed}\ <\ \mathrm{Integer}\ <\ \mathrm{Real}\ <\ \mathrm{Number}
\end{aligned}


という階層関係がある。階層関係は\lt :もしくは\gt:で比較できる。
 型には階層関係はあるため、パラメトリック型は不変であるため、定義した型とは異なるより階層の高い型の値を後から指定することはできない。

# 型は不変であるから、他の方を与えることは出来ない
function distance(p::Point{Number})
    # 何らかの処理
end

### 型に自由度を与えつつある程度の制約を掛けるのであれば以下のように指定する
function distance(p::Point{<:Number})
    # 何らかの処理
end
# もしくは    
function distance(p::Point{T}) where T<:Number
    # 何らかの処理
end
プライバシーポリシー お問い合わせ