फ़ंक्शन तर्कों के लिए डिफ़ॉल्ट मानों को परिभाषित करें


86

लुआ विकी में मुझे लापता तर्कों के लिए डिफ़ॉल्ट मूल्यों को परिभाषित करने का एक तरीका मिला:

function myfunction(a,b,c)
    b = b or 7
    c = c or 5
    print (a,b,c)
end

क्या यह एकमात्र तरीका है? PHP शैली myfunction (a,b=7,c=5)काम नहीं करती है। ऐसा नहीं है कि लुआ रास्ता काम नहीं करता है, मैं सोच रहा हूं कि क्या यह ऐसा करने का एकमात्र तरीका है।

जवाबों:


86

यदि आप PHP या पाइथन जैसे तर्क और डिफ़ॉल्ट मान चाहते हैं, तो आप अपने कार्य को टेबल कंस्ट्रक्टर के साथ कॉल कर सकते हैं:

myfunction{a,b=3,c=2}

(यह इस तरह के रूप लुआ में कई स्थानों पर, में देखा जाता है LuaSocket के प्रोटोकॉल मॉड्यूल के उन्नत रूपों और में कंस्ट्रक्टर्स IUPLua ।)

फ़ंक्शन में इस तरह से एक हस्ताक्षर हो सकता है:

function myfunction(t)
    setmetatable(t,{__index={b=7, c=5}})
    local a, b, c =
      t[1] or t.a, 
      t[2] or t.b,
      t[3] or t.c
    -- function continues down here...
end

मापदंडों की तालिका से गायब किसी भी मान __indexको इसकी मेटािटेबल तालिका में लिया जाएगा ( मेटाटैबल्स पर प्रलेखन देखें )।

बेशक, टेबल कंस्ट्रक्टर और फ़ंक्शंस का उपयोग करके अधिक उन्नत पैरामीटर शैलियां संभव हैं- आप जो भी लिख सकते हैं उसकी आवश्यकता है। उदाहरण के लिए, यहां एक फ़ंक्शन है जो एक फ़ंक्शन का निर्माण करता है जो पैरामीटर नाम और डिफ़ॉल्ट मानों को परिभाषित करने वाली तालिका से नाम-या-स्थितीय तर्क तालिकाओं को लेता है और एक फ़ंक्शन जो एक नियमित तर्क सूची लेता है।

एक गैर-भाषा-स्तरीय सुविधा के रूप में, नए व्यवहार और शब्दार्थ प्रदान करने के लिए इस तरह की कॉल को बदला जा सकता है:

  • चर को एक से अधिक नामों को स्वीकार करने के लिए बनाया जा सकता है
  • स्थितीय चरों और खोजशब्द चरों को परस्पर जोड़ा जा सकता है - और दोनों को परिभाषित करना या तो पूर्वता दे सकता है (या त्रुटि का कारण हो सकता है)
  • कीवर्ड-केवल पोजिशनलेस वैरिएबल बनाए जा सकते हैं, साथ ही नॉर्मल पोजिशन-ओनली भी
  • एक स्ट्रिंग को पार्स करके काफी-वर्बोज़ टेबल निर्माण किया जा सकता है
  • यदि फ़ंक्शन 1 टेबल के अलावा किसी अन्य चीज़ से कॉल किया जाता है, तो तर्क सूची का उपयोग शब्दशः किया जा सकता है

तर्क अनुवादक लिखने के लिए कुछ उपयोगी कार्य unpack( table.unpack5.2 में चल रहे हैं ), setfenv(नए _ENVनिर्माण के साथ 5.2 में पदावनत ), और select(जो किसी दिए गए तर्क सूची से एकल मान लौटाता है, या सूची की लंबाई '#')।


एआई ने बस लुआ का उपयोग करना शुरू किया मैं इसे समय के लिए सरल रखूंगा लेकिन आपकी पोस्ट बहुत जानकारीपूर्ण है। बाद में काम आ सकता है। धन्यवाद।
शाम

1
ज्यादातर मामलों में, इसे सरल रखना ही रास्ता तय करना है। मेटा-पैरामीटर इंटरफ़ेस वास्तव में केवल बड़ी संख्या में वैकल्पिक विशेषताओं (जैसे UI ऑब्जेक्ट) के साथ ऑब्जेक्ट्स के लिए आवश्यक हैं।
स्टुअर्ट पी। बेंटले

मुझे लगता है कि यह उत्तर वह है जो प्रश्नों को हल करता है, न कि वर्तमान में स्वीकृत के रूप में चिह्नित। प्रबोधन के लिए धन्यवाद :)
पूर्ववत करें

1
ऐसा लगता है कि x or defaultअभिव्यक्ति भी इस उत्तर में प्रयोग किया जाता है वास्तव में पैरामीटर डिफ़ॉल्ट रूप में एक सच्चे बराबर लेकिन सिर्फ एक साधारण workaround कि तभी काम करता है दोनों नहीं है nilऔर falseअवैध पैरामीटर मान रहे हैं। मान लें कि एक बूलियन पैरामीटर के लिए डिफ़ॉल्ट xहै trueऔर कॉल करने वाला स्पष्ट है false। फिर x or trueदेता है true, भले ही falseस्पष्ट रूप से पारित किया गया था। एक बेहतर संस्करण होगा if x == nil then x = default end, जो अधिक पठनीय है; nilहालांकि यह अभी भी स्पष्ट तर्कों को संभाल नहीं सकता है ।
जेसपर

ओह, हे, यह अब स्वीकृत उत्तर है! अच्छा लगा। (रिकॉर्ड के लिए, और संदर्भ में @ अंडो की टिप्पणी डालने के लिए, नीचे दिए गए जवाब में jpjacobs का जवाब बहुत लंबे समय के लिए स्वीकार किया गया था: मुझे लगभग इस पर दूसरा पॉपुलिस्ट बैज मिला ।)
स्टुअर्ट पी। बेंटले

46

मेरी राय में दूसरा रास्ता नहीं है। यह सिर्फ लुआ मानसिकता है: कोई तामझाम नहीं है, और कुछ सिंटैक्टिक चीनी को छोड़कर, साधारण चीजें करने का कोई निरर्थक तरीका नहीं है।


10
यह उत्तर स्टुअर्ट पी। बेंटले के जवाब से पूरी तरह से अस्वीकृत है, जिसमें फ़ंक्शन को टेबल कंस्ट्रक्टर के साथ कहा जाता है। यह लुआ की खूबियों में से एक है: जबकि इसमें तामझाम नहीं होता है, लुआ के मूलभूत भवन खंड आपको असीम चीजें करने की अनुमति देते हैं, जो वास्तव में भाषा के छोटे आकार और सादगी के लिए उल्लेखनीय हैं।
कॉलिन डी बेनेट

@ColinDBennett बोलने के लिए धन्यवाद: ऐसा प्रतीत होता है कि ओपी आपकी टिप्पणी को पढ़ेगा और उस दिसंबर को तदनुसार स्वीकृत उत्तर को बदल देगा। (और अब यह "स्टुअर्ट पी। बेंटले का उत्तर है", स्पष्टता के लिए: विंक :)
स्टुअर्ट पी। बेंटले

21

तकनीकी रूप से, वहां b = b == nil and 7 or b(जिसका उपयोग उस मामले में किया जाना चाहिए जहां 7 के मूल्यांकन के falseरूप में एक वैध मूल्य है false or 7), लेकिन यह शायद वह नहीं है जो आप खोज रहे हैं।


1
यदि आप के लिए जाँच नहीं कर रहे हैं false, एक आसान तरीका चर पहले और डिफ़ॉल्ट अंतिम डाल रहा है। b = b or 7
रीब

2
चूंकि ओपी ने कहा कि उनके प्रश्न में, मुझे लगा कि यह उल्लेख करना अतिश्योक्तिपूर्ण होगा (यह प्रश्न अन्य तरीकों के अलावा डिफ़ॉल्ट चर को परिभाषित करने के तरीकों के बारे में था b = b or 7)।
स्टुअर्ट पी। बेंटले

6

एकमात्र तरीका जो मैंने अब तक पाया है कि किसी भी तरह से कुछ करना है:

function new(params)
  params = params or {}
  options = {
    name = "Object name"
  }

  for k,v in pairs(params) do options[k] = v end

  some_var = options.name
end

new({ name = "test" })
new()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.