У Джулии есть функции сеттера 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
понижается к [1 113] с нейтрализацией по умолчанию
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"
, Таким образом, мы можем добавить дополнительную функциональность к точечному синтаксису (динамично, если мы хотим). Поскольку конкретным примером, где это полезно, является для пакета PyCall.jl, где Вы раньше писали pyobject[:field]
, в то время как возможно теперь реализовать его таким образом, что можно записать pyobject.field.
, различие между [1 118] и setproperty!
походит на различие между [1 120] и getproperty
, объясненный выше.
, Кроме того, возможно сцепиться в функцию Base.propertynames
для обеспечения заполнения клавишей Tab свойств в REPL. По умолчанию только имена полей покажут:
julia> a.<TAB><TAB>
b c
, Но путем перегрузки propertynames
мы можем заставить его также показать дополнительное свойство q
:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q