Julia構造体の変更可能なフィールド 質問する

Julia構造体の変更可能なフィールド 質問する

次の「設計上の問題」に対する答えは、stackoverflow と Julia ドキュメントの両方で見つけることができませんでした。

次のようなオブジェクトを定義したいとします

struct Person
birthplace::String
age::Int
end

は不変なので、誰も作成したをPerson変更できないのは嬉しいことですが、それはまた、時間が経つと、私も変更できなくなることを意味します...birthplacePersonage

一方、型をPerson次のように定義すると

mutable struct Person
birthplace::String
age::Int
end

今では を作成できますageが、 で以前持っていた安全性はなくbirthplace、誰でもアクセスして変更することができます。

これまでに見つけた回避策は次のとおりです

struct Person
birthplace::String
age::Vector{Int}
end

ここで、 は明らかにage1 要素ですVector
このソリューションは非常に見苦しく、毎回角括弧で年齢にアクセスする必要があるため、明らかに最適ではないと思います。

オブジェクト内に不変フィールドと可変フィールドの両方を持つ、よりエレガントな方法は他にありますか?

おそらく問題は、 内ですべてを可変または不変にすることの真の価値を私が見逃していることですstruct。もしそうなら、それを説明していただけますか?

ベストアンサー1

この特定の例では、生年月日も不変であり、その情報から年齢を計算するのは簡単なので、年齢よりも生年月日を保存する方が適切と思われますが、これは単なる例に過ぎないかもしれません。


この解決策は、毎回角括弧を使って年齢にアクセスする必要があるため、かなり見苦しく、明らかに最適ではないと思います。

age(p::Person) = p.age[1]通常、フィールドに直接アクセスする代わりに、ゲッター、つまり使用するものを定義します。これにより、括弧による「醜さ」を回避できます。

Refこの場合、単一の値のみを格納したいので、次のように (または 0 次元のArray)を使用することもできます。

struct Person
    birthplace::String
    age::Base.RefValue{Int}
end
Person(b::String, age::Int) = Person(b, Ref(age))
age(p::Person) = p.age[]

使用法:

julia> p = Person("earth", 20)
Person("earth", 20)

julia> age(p)
20

おすすめ記事