В чем разница между полями и свойствами в Юлии?

У Джулии есть функции сеттера 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)
20
задан Kristoffer Carlsson 1 October 2019 в 08:25
поделиться

1 ответ

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
26
ответ дан 29 November 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: