前提
自作の型に対して足し算とか配列のようなアクセスができると都合が良いことがあります。
今回は、以下のような構造体を型として扱います。
mutable struct Status_6
hp::Real
mp::Real
atk::Real
dfs::Real
end
この構造体に対して、ステータスの増加を見通し良く行うため、以下のような記述ができると便利そうです。
st + Δst
今回はこれの実装方法を説明します。
自作の型に対する演算
ステータスのアクセスに対して、配列のアクセスのようにインデックスでアクセスしたい場合、以下のようにして定義すれば可能になります。これはBase
の関数getindex
, setindex!
に対して多重ディスパッチさせている感じです。
function Base.getindex(st::Status_6, i::Int)
if i == 1 return st.hp
elseif i == 2 return st.mp
elseif i == 3 return st.atk
elseif i == 4 return st.dfs
else error("access denied.")
end
end
function Base.setindex!(st::Status_6, val::Real, i::Int)
if i == 1 st.hp = val
elseif i == 2 st.mp = val
elseif i == 3 st.atk = val
elseif i == 4 st.dfs = val
else error("access denied.")
end
end
これで以下のようなアクセスが可能となります。勿論、文字列やシンボルでアクセスしたり、タプルや配列によるアクセスを可能とすることもできます。自作の配列型みたいなのを作れるってことですね。
st = Status_6(10, 11, 6, 5)
st[3]
copy
関数も自作で作れます。
Base.copy(st::Status_6) = Status_6(st.hp, st.mp, st.atk, st.dfs)
レベルアップなどでステータス全体に対して変化分のステータスを足し合わせたい場合、以下のようにして定義すれば足し算を定義することも可能です。
function Base.:+(st::Status_6, Δst::Status_6)
new_st = copy(st)
for i = 1:4
new_st[i] = st[i] + Δst[i]
end
return new_st
end
これで、ステータスの足し算のようなものが実装できました。
実際に以下のように動作せることができます。
st = Status_6(10, 11, 6, 5)
Δst = Status_6(2, 2, 1, 1)
st + Δst