fieldssono semplicemente i "componenti" di una struttura. La struttura
struct A
b
c::Int
end
ha i campi be c. Una chiamata per getfieldrestituire l'oggetto associato al campo:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
Nelle prime versioni di Julia, la sintassi a.butilizzata per "abbassare", ovvero essere la stessa della scrittura getfield(a, :b). Ciò che è cambiato ora è che si a.briduce a getproperty(a, :b)con il fallback predefinito
getproperty(a::Type, v::Symbol) = getfield(a, v)
Quindi, per impostazione predefinita, nulla è cambiato. Tuttavia, gli autori di strutture possono sovraccaricare getproperty(non è possibile sovraccaricare getfield) per fornire funzionalità extra alla sintassi punto:
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"
Quindi possiamo aggiungere funzionalità extra alla sintassi del punto (dinamicamente se vogliamo). Un esempio concreto in cui ciò è utile è per il pacchetto PyCall.jl in cui era necessario scrivere pyobject[:field] mentre ora è possibile implementarlo in modo tale da poter scriverepyobject.field.
La differenza tra setfield!e setproperty!è analoga alla differenza tra getfielde getproperty, spiegata sopra.
Inoltre, è possibile collegarsi alla funzione Base.propertynamesper fornire il completamento con tabulazione delle proprietà nella REPL. Per impostazione predefinita, verranno visualizzati solo i nomi dei campi:
julia> a.<TAB><TAB>
b c
Ma sovraccaricandoci propertynamespossiamo fargli mostrare anche la proprietà extra q:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q