Julia'daki alanlar ve mülkler arasındaki fark nedir?


23

Julia'nın setter işlevleri setproperty!ve setfield!ve getter işlevleri vardır getpropertyve getfieldbu yapılar üzerinde çalışır. Julia'daki mülkler ve alanlar arasındaki fark nedir?

Örneğin, aşağıdakiler aynı şeyi yaptıklarını göstermektedir:

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)

Yanıtlar:


27

fieldsbasitçe bir yapının "bileşenleridir". Yapı

struct A
   b
   c::Int
end

alanları vardır bve c. getfieldAlana bağlı nesneyi döndürmek için bir çağrı :

julia> a = A("foo", 3)
A("foo", 3)

julia> getfield(a, :b)
"foo"

Julia'nın ilk versiyonlarında, sözdizimi a.b"indirgemek", yani yazmakla aynı anlama gelirdi getfield(a, :b). Şimdi ne değişti olmasıdır a.biçin düşürür getproperty(a, :b)varsayılan yedek kullanımıyla

getproperty(a::Type, v::Symbol) = getfield(a, v)

Yani varsayılan olarak hiçbir şey değişmedi. Bununla birlikte, yapı yazarları nokta sözdizimine ekstra işlevsellik sağlamak getpropertyiçin aşırı yüklenebilir ( aşırı yüklenmek mümkün değildir 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"

Böylece nokta sözdizimine ekstra işlevsellik ekleyebiliriz (istersek dinamik olarak). Bunun yararlı olduğu somut bir örnek olarak, eskiden yazmak zorunda kaldığınız PyCall.jl paketi için pyobject[:field] yazabilirsiniz.pyobject.field.

Arasındaki fark setfield!ve setproperty!arasındaki fark benzer olan getfieldve getpropertyyukarıda açıklandığı.

Ek olarak, Base.propertynamesREPL'deki özelliklerin sekme tamamlanmasını sağlamak için işleve bağlanmak da mümkündür . Varsayılan olarak, yalnızca alan adları gösterilir:

julia> a.<TAB><TAB>
b c

Ancak aşırı propertynamesyükleyerek, ekstra özelliği de gösterebiliriz q:

julia> Base.propertynames(::A) = (:b, :c, :q)

julia> a.<TAB><TAB>
b c q

Yani getfield'ı aşırı yükleyemiyor musunuz?
Alfaizkhan

3
Hayır, getfieldözel (yerleşik) bir işlevdir. Aşırı yüklemeye çalışmak hatayı verecektir cannot add methods to a builtin function.
Kristoffer Carlsson

Belki bu bilgiyi bir yere cevaba ekleyebilirsin?
StefanKarpinski

2
Cevap zaten açıkça "(aşırı yüklenmek mümkün değil getfield)" diyor, yani bir anlamda zaten orada.
Kristoffer Carlsson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.