fieldssą po prostu „komponentami” struktury. Struktura
struct A
b
c::Int
end
ma pola bi c. Wywołanie getfieldzwracające obiekt związany z polem:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
We wczesnych wersjach Julii składnia a.bużywana była do „obniżania”, tj. Bycia takim samym jak pisanie getfield(a, :b). To, co się teraz zmieniło, to a.bobniżenie do getproperty(a, :b)domyślnego stanu rezerwowego
getproperty(a::Type, v::Symbol) = getfield(a, v)
Domyślnie nic się nie zmieniło. Jednak autorzy struktur mogą przeciążać getproperty(nie można przeciążać getfield), aby zapewnić dodatkową funkcjonalność składni kropek:
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"
Możemy więc dodać dodatkową funkcjonalność do składni kropek (dynamicznie, jeśli chcemy). Konkretnym przykładem, w którym jest to przydatne, jest pakiet PyCall.jl, w którym kiedyś musiałeś pisać pyobject[:field] , ale teraz możesz go zaimplementować tak, abyś mógł pisaćpyobject.field.
Różnica między setfield!i setproperty!jest analogiczna do różnicy między getfieldi getproperty, wyjaśnionej powyżej.
Ponadto możliwe jest podpięcie się do funkcji w Base.propertynamescelu zapewnienia uzupełnienia tabulacji właściwościami w REPL. Domyślnie wyświetlane są tylko nazwy pól:
julia> a.<TAB><TAB>
b c
Ale przez przeciążenie propertynamesmożemy sprawić, że pokaże także dodatkową właściwość q:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q