fields
sont simplement les "composants" d'une structure. La struct
struct A
b
c::Int
end
a les champs b
et c
. Un appel à getfield
renvoie l'objet qui est lié au champ:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
Dans les premières versions de Julia, la syntaxe a.b
utilisée pour "abaisser", c'est-à-dire être la même que pour l'écriture getfield(a, :b)
. Ce qui a changé maintenant, c'est que l' a.b
abaissement de getproperty(a, :b)
la valeur par défaut
getproperty(a::Type, v::Symbol) = getfield(a, v)
Donc par défaut, rien n'a changé. Cependant, les auteurs de structures peuvent surcharger getproperty
(il n'est pas possible de surcharger getfield
) pour fournir des fonctionnalités supplémentaires à la syntaxe à points:
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"
Nous pouvons donc ajouter des fonctionnalités supplémentaires à la syntaxe des points (dynamiquement si nous voulons). Un exemple concret où cela est utile est pour le package PyCall.jl où vous aviez l'habitude d'écrire pyobject[:field]
alors qu'il est maintenant possible de l'implémenter de telle sorte que vous puissiez écrirepyobject.field.
La différence entre setfield!
et setproperty!
est analogue à la différence entre getfield
et getproperty
, expliquée ci-dessus.
De plus, il est possible de se connecter à la fonction Base.propertynames
pour fournir une tabulation des propriétés dans le REPL. Par défaut, seuls les noms de champs seront affichés:
julia> a.<TAB><TAB>
b c
Mais en surchargeant, propertynames
nous pouvons également faire apparaître la propriété supplémentaire q
:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q