fields
sind einfach die "Komponenten" einer Struktur. Die Struktur
struct A
b
c::Int
end
hat die Felder b
und c
. Ein Aufruf zum getfield
Zurückgeben des an das Feld gebundenen Objekts:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
In früheren Versionen von Julia wurde die Syntax a.b
zum "Verringern" verwendet, dh dieselbe wie beim Schreiben getfield(a, :b)
. Was sich jetzt geändert hat, ist, dass a.b
es sich getproperty(a, :b)
mit dem Standard-Fallback verringert
getproperty(a::Type, v::Symbol) = getfield(a, v)
Standardmäßig hat sich also nichts geändert. Autoren von Strukturen können jedoch überladen getproperty
(eine Überladung ist nicht möglich getfield
), um der Punktsyntax zusätzliche Funktionen bereitzustellen:
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"
So können wir der Punktsyntax zusätzliche Funktionen hinzufügen (dynamisch, wenn wir möchten). Ein konkretes Beispiel, in dem dies nützlich ist, ist das Paket PyCall.jl, in dem Sie früher schreiben mussten, pyobject[:field]
während es jetzt möglich ist, es so zu implementieren, dass Sie schreiben könnenpyobject.field.
Der Unterschied zwischen setfield!
und setproperty!
ist analog zu dem oben erläuterten Unterschied zwischen getfield
und getproperty
.
Darüber hinaus ist es möglich, sich in die Funktion Base.propertynames
einzuhängen, um die Eigenschaften der REPL auf der Registerkarte zu vervollständigen. Standardmäßig werden nur die Feldnamen angezeigt:
julia> a.<TAB><TAB>
b c
Durch Überladen können propertynames
wir aber auch die zusätzliche Eigenschaft anzeigen lassen q
:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q