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снижается до уровня getproperty(a, :b)по умолчанию
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.
Разница между setfield!и setproperty!аналогична разнице между getfieldи getproperty, поясненной выше.
Кроме того, можно подключиться к функции, Base.propertynamesчтобы обеспечить завершение свойств вкладки в REPL. По умолчанию будут показаны только имена полей:
julia> a.<TAB><TAB>
b c
Но, перегрузив, propertynamesмы можем сделать так, чтобы он также показывал дополнительное свойство q:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q