ジュリアにはセッター関数setproperty!
およびsetfield!
と、構造体を操作するゲッター関数getproperty
とgetfield
ジュリアのプロパティとフィールドの違いは何ですか?
たとえば、次の例は同じことを示しているようです。
Julia> mutable struct S
a
end
Julia> s = S(2)
S(2)
Julia> getfield(s, :a)
2
Julia> getproperty(s, :a)
2
Julia> setfield!(s, :a, 3)
3
Julia> s
S(3)
Julia> setproperty!(s, :a, 4)
4
Julia> s
S(4)
fields
は単に構造体の「コンポーネント」です。構造体
_struct A
b
c::Int
end
_
フィールドb
およびc
があります。 getfield
を呼び出すと、フィールドにバインドされているオブジェクトが返されます。
_Julia> a = A("foo", 3)
A("foo", 3)
Julia> getfield(a, :b)
"foo"
_
Juliaの初期のバージョンでは、構文_a.b
_は「低く」使用されていました。つまり、getfield(a, :b)
を記述するのと同じです。現在変更されているのは、デフォルトのフォールバックで_a.b
_がgetproperty(a, :b)
に低下することです。
_getproperty(a::Type, v::Symbol) = getfield(a, v)
_
したがって、デフォルトでは何も変更されていません。ただし、構造体の作成者はgetproperty
をオーバーロードして(getfield
をオーバーロードすることはできません)、ドット構文に追加の機能を提供できます。
_Julia> function Base.getproperty(a::A, v::Symbol)
if v == :c
return getfield(a, :c) * 2
elseif v == :q
return "q"
else
return getfield(a, v)
end
end
Julia> a.q
"q"
Julia> getfield(a, :q)
ERROR: type A has no field q
Julia> a.c
6
Julia> getfield(a, :c)
3
Julia> a.b
"foo"
_
したがって、ドット構文に機能を追加できます(必要に応じて動的に)。これが役立つ具体的な例としては、以前は_pyobject[:field]
_を記述しなければならなかったパッケージPyCall.jlがありますが、今では_pyobject.field.
_を記述できるように実装することが可能です。
_setfield!
_と_setproperty!
_の違いは、上記で説明したgetfield
とgetproperty
の違いに似ています。
さらに、REPLでプロパティのタブ補完を提供するために、関数_Base.propertynames
_にフックすることが可能です。デフォルトでは、フィールド名のみが表示されます。
_Julia> a.<TAB><TAB>
b c
_
しかし、propertynames
をオーバーロードすることで、追加のプロパティq
も表示させることができます。
_Julia> Base.propertynames(::A) = (:b, :c, :q)
Julia> a.<TAB><TAB>
b c q
_