जूलिया में खेतों और संपत्तियों के बीच अंतर क्या है?


23

जूलिया में सेटर फ़ंक्शंस 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)

जवाबों:


27

fieldsबस एक संरचना के "घटक" हैं। संरचना

struct A
   b
   c::Int
end

खेतों bऔर है cgetfieldफ़ील्ड के लिए बाध्य ऑब्जेक्ट को वापस करने के लिए एक कॉल :

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.propertynamesREPL में संपत्तियों की टैब पूर्णता प्रदान करने के लिए फ़ंक्शन में हुक करना संभव है । डिफ़ॉल्ट रूप से, केवल फ़ील्ड नाम दिखाए जाएंगे:

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

लेकिन ओवरलोडिंग से propertynamesहम इसे अतिरिक्त संपत्ति भी दिखा सकते हैं q:

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

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

तो आप getfield को अधिभार नहीं कर सकते?
अल्फिज़खान

3
नहीं, getfieldएक विशेष (अंतर्निहित) फ़ंक्शन है। इसे ओवरलोड करने की कोशिश करने से त्रुटि होगी cannot add methods to a builtin function
क्रिस्टोफर कार्ल्ससन

शायद उस जानकारी को कहीं उत्तर में जोड़ दें?
स्टीफनकर्पिन्स्की

2
उत्तर पहले से ही स्पष्ट रूप से कहता है "(यह अधिभार के लिए संभव नहीं है getfield") इसलिए, एक अर्थ में, यह पहले से ही है।
क्रिस्टोफर कार्लसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.