के बीच अंतर । और: लुआ में


174

मैं फ़ंक्शन कॉल के माध्यम से .और इसके माध्यम से अंतर के बारे में उलझन में हूं:

> x = {foo = function(a,b) return a end, bar = function(a,b) return b end, }
> return x.foo(3,4)
3
> return x.bar(3,4)
4
> return x:foo(3,4)
table: 0x10a120
> return x:bar(3,4)
3

क्या :कर रहा है?


जवाबों:


237

बृहदान्त्र उन तरीकों को लागू करने के लिए है जो selfपहले पैरामीटर के रूप में गुजरते हैं । तो x:bar(3,4)जैसा होना चाहिए वैसा ही होना चाहिए x.bar(x,3,4)


55
आह ... तो यह ऑब्जेक्ट-ओरिएंटेड सिनेटिक शुगर है।
जेसन एस

7
बिल्कुल सही। पूरे संदर्भ मैनुअल में, वे इस पर केवल एक ही दोष देते हैं "कोलोन सिंटैक्स का उपयोग परिभाषित करने के तरीकों के लिए किया जाता है, अर्थात्, ऐसे कार्य जिनमें एक अंतर्निहित अतिरिक्त पैरामीटर स्वयं है।" (5.0 मैनुअल, पीडीएफ पेज 19 के नीचे)
BMitch

2
ऊह आह ... मैं पूछने जा रहा था कि इस पर आधिकारिक डॉक्स कहाँ थे, लेकिन आपने मुझे इसके लिए हराया। अच्छी तरह से किया। :-)
जेसन एस

1
@keyle यह इस बात पर निर्भर करता है कि selfऑब्जेक्ट पहले पैरामीटर और उसके गुण मान के रूप में जाएगा।
जलप्रपात

8
वर्चुअल मशीन केवल एक बार प्राप्त करने के बाद से @keyle कोलोन सिंटैक्स थोड़ा तेज़ होगा यदि आप जिस ऑब्जेक्ट को कॉल कर रहे हैं वह स्थानीय नहीं है। मूल रूप से डॉट सिंटैक्स दो बार object.method(object,args)पुनर्प्राप्त करता है object, जबकि केवल एक बार object:method(arg)पुनर्प्राप्त objectकरता है। यदि objectएक वैश्विक, उत्थान या तालिका क्षेत्र है, तो इससे :भी तेज है ..से तेज कभी नहीं है :
नेगामार्टिन

28

परिभाषा के लिए यह है कि वास्तव में मैन्युअल रूप से स्वयं को निर्दिष्ट के रूप में ही है - यह भी संकलन पर एक ही बाईटकोड का उत्पादन करेगा। यानी function object:method(arg1, arg2)रूप में ही है function object.method(object, arg1, arg2)

उपयोग :पर लगभग समान है .- यह सुनिश्चित करने के लिए आंतरिक रूप से एक विशेष प्रकार की कॉल का उपयोग किया जाएगा objectऔर गणना / पहुंच के किसी भी संभावित दुष्प्रभाव की गणना केवल एक बार की जाएगी। कॉलिंग object:method(arg1, arg2)अन्यथा के रूप में ही है object.method(object, arg1, arg2)


21

पूरी तरह से सटीक होने के लिए, के obj:method(1, 2, 3)रूप में ही है

do
  local _obj = obj
  _obj.method(_obj, 1, 2, 3)
end

स्थानीय चर क्यों? क्योंकि, कई ने बताया है, obj:method()केवल _ENVएक बार प्राप्त करने के लिए अनुक्रमित obj। गति पर विचार करते समय यह आमतौर पर सिर्फ महत्वपूर्ण होता है, लेकिन इस स्थिति पर विचार करें:

local tab do
  local obj_local = { method = function(self, n) print n end }
  tab = setmetatable({}, {__index = function(idx)
    print "Accessing "..idx
    if idx=="obj" then return obj_local end
  end})
end
tab.obj.method(tab.obj, 20)
--> Accessing obj
--> Accessing obj
--> 20
tab.obj:method(10)
--> Accessing obj
--> 10

अब कल्पना कीजिए कि __indexमेटामेथोड ने केवल कुछ छापने से ज्यादा किया। कल्पना कीजिए कि यह एक काउंटर बढ़ा, किसी फ़ाइल में कुछ लॉग किया या आपके डेटाबेस से एक यादृच्छिक उपयोगकर्ता को हटा दिया। दो बार या केवल एक बार करने के बीच एक बड़ा अंतर है। इस मामले में, obj.method(obj, etc)और के बीच एक स्पष्ट अंतर है obj:method(etc)


आपको वास्तव में ऐसे सामान की चिंता नहीं करनी चाहिए। यदि आपके पास है, तो आपकी वास्तुकला में बहुत कुछ गलत है।
वैल का कहना है कि मोनिका

2
मैं कहता हूँ कि यह दूसरा रास्ता है; अच्छा कोड असंबंधित कोड के कार्यान्वयन के विवरण के बारे में कोई धारणा नहीं बनाना चाहिए। फ़ंक्शन कॉल को याद किया जा सकता है या नहीं किया जा सकता है, इसका मतलब यह नहीं है कि उन्हें ज़रूरत से ज़्यादा बार कॉल करना अच्छा अभ्यास है।
DarkWiiPlayer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.