fields
просто "компоненти" структури. Структура
struct A
b
c::Int
end
має поля b
і c
. Заклик доgetfield
повернути об'єкт, який пов'язаний з полем:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
У ранніх версіях Джулії синтаксис 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