fields
hanyalah "komponen" dari sebuah struct. Struct
struct A
b
c::Int
end
memiliki bidang b
dan c
. Panggilan untuk getfield
mengembalikan objek yang terikat ke bidang:
julia> a = A("foo", 3)
A("foo", 3)
julia> getfield(a, :b)
"foo"
Dalam versi awal Julia, sintaksinya a.b
digunakan untuk "lebih rendah", yaitu sama dengan, menulis getfield(a, :b)
. Apa yang telah berubah sekarang adalah semakin a.b
rendah getproperty(a, :b)
dengan fallback default
getproperty(a::Type, v::Symbol) = getfield(a, v)
Jadi secara default, tidak ada yang berubah. Namun, penulis struct dapat membebani berlebihan getproperty
(tidak mungkin membebani berlebihan getfield
) untuk menyediakan fungsionalitas tambahan untuk sintaks dot:
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"
Jadi kita dapat menambahkan fungsionalitas tambahan ke sintaks dot (secara dinamis jika kita mau). Sebagai contoh konkret di mana ini berguna adalah untuk paket PyCall.jl di mana Anda dulu harus menulis pyobject[:field]
sementara mungkin sekarang untuk mengimplementasikannya sehingga Anda dapat menulispyobject.field.
Perbedaan antara setfield!
dan setproperty!
analog dengan perbedaan antara getfield
dan getproperty
, dijelaskan di atas.
Selain itu, dimungkinkan untuk menghubungkan ke fungsi Base.propertynames
untuk menyediakan penyelesaian tab properti di REPL. Secara default, hanya nama bidang yang akan ditampilkan:
julia> a.<TAB><TAB>
b c
Tetapi dengan kelebihan beban propertynames
kita dapat membuatnya juga menunjukkan properti tambahan q
:
julia> Base.propertynames(::A) = (:b, :c, :q)
julia> a.<TAB><TAB>
b c q
getfield
adalah fungsi khusus (bawaan). Mencoba membebani itu akan memberikan kesalahancannot add methods to a builtin function
.getfield
)" jadi, dalam arti, sudah ada di sana.