Lua
वैरेडिक तर्क
खोज…
परिचय
Varargs , जैसा कि वे आमतौर पर जाना जाता है, कार्यों को बिना विनिर्देश के मनमानी संख्या लेने की अनुमति देता है। ऐसे फ़ंक्शन के लिए दिए गए सभी तर्कों को एक एकल संरचना में पैक किया जाता है जिसे वार्ग सूची के रूप में जाना जाता है; जो लिखा है ...
लुआ में। दिए गए तर्कों की संख्या और select()
फ़ंक्शन का उपयोग करके उन तर्कों के मूल्य को निकालने के लिए बुनियादी तरीके हैं, लेकिन अधिक उन्नत उपयोग पैटर्न इसकी पूर्ण उपयोगिता के लिए संरचना का लाभ उठा सकते हैं।
वाक्य - विन्यास
- ... - वह फ़ंक्शन बनाता है जिसके तर्कों की सूची जिसमें यह एक वैरेडिक फ़ंक्शन दिखाई देता है
- चयन करें (क्या, ...) - यदि '1' वेरिएग में तत्वों की संख्या की सीमा 1 की संख्या में है, तो वेरग में अंतिम तत्व के लिए 'what'th' तत्व देता है। यदि सूचकांक सीमा से बाहर है, तो रिटर्न शून्य होगा। यदि 'क्या' स्ट्रिंग '#' है, तो वार्ग में तत्वों की संख्या लौटाता है।
टिप्पणियों
दक्षता
वेरग सूची को भाषा के पीयूसी-रियो कार्यान्वयन में एक लिंक्ड सूची के रूप में लागू किया गया है, इसका मतलब है कि अनुक्रमित ओ (एन) हैं। इसका मतलब है कि select()
का उपयोग करके एक varar में तत्वों पर पुनरावृति, नीचे दिए गए उदाहरण की तरह, एक O (n ^ 2) ऑपरेशन है।
for i = 1, select('#', ...) do
print(select(i, ...))
end
यदि आप एक vararg सूची में तत्वों पर पुनरावृत्ति की योजना बनाते हैं, तो पहले सूची को एक तालिका में पैक करें। तालिका पहुंच O (1) है, इसलिए पुनरावृति कुल में O (n) है। या, यदि आप इतने इच्छुक हैं, तो उन्नत उपयोग अनुभाग से foldr()
उदाहरण देखें; यह O (n) में एक vararg सूची पर पुनरावृति का उपयोग करता है।
अनुक्रम लंबाई परिभाषा;
यह वैरग उपयोगी है कि वार्ग की लंबाई किसी भी स्पष्ट रूप से पारित (या गणना) निल्स का सम्मान करती है। उदाहरण के लिए।
function test(...)
return select('#', ...)
end
test() --> 0
test(nil, 1, nil) --> 3
यह व्यवहार तालिकाओं के व्यवहार के साथ संघर्ष करता है, जहां लंबाई ऑपरेटर #
दृश्यों में 'छेद' (एम्बेडेड निल्स) के साथ काम नहीं करता है। छेद के साथ एक तालिका की लंबाई की गणना अपरिभाषित है और इस पर भरोसा नहीं किया जा सकता है। इसलिए, ...
में मानों के आधार पर, {...}
की लंबाई लेने से 'सही' उत्तर नहीं मिल सकता है। Lua में 5.2+ table.pack()
इस कमी को संभालने के लिए पेश किया गया था (उदाहरण में एक फ़ंक्शन है जो शुद्ध Lua में इस फ़ंक्शन को लागू करता है)।
मुहावरेदार उपयोग
क्योंकि varargs उनकी लंबाई के चारों ओर ले जाता है, लोग तालिकाओं में छेद के साथ समस्या से बचने के लिए अनुक्रम के रूप में उनका उपयोग करते हैं। यह उनका इच्छित उपयोग नहीं था और लुआ का एक संदर्भ कार्यान्वयन इसके लिए अनुकूलन नहीं करता है। हालांकि इस तरह के उपयोग को उदाहरणों में खोजा गया है, लेकिन यह आमतौर पर पर आधारित है।
मूल बातें
Variadic फ़ंक्शन का उपयोग किया जाता है ...
फ़ंक्शन परिभाषा की तर्क सूची में दीर्घवृत्त सिंटैक्स।
function id(...)
return
end
यदि आपने इस फ़ंक्शन को id(1, 2, 3, 4, 5)
तो ...
(AKA the vararg list) में मान 1, 2, 3, 4, 5
।
फ़ंक्शंस आवश्यक तर्क भी ले सकते हैं ...
function head(x, ...)
return x
end
वेरग लिस्ट से तत्वों को खींचने का सबसे आसान तरीका बस इससे वेरिएबल असाइन करना है।
function head3(...)
local a, b, c = ...
return a, b, c
end
select()
उपयोग तत्वों की संख्या को खोजने और तत्वों को निकालने के लिए भी किया जा सकता है ...
अप्रत्यक्ष रूप से।
function my_print(...)
for i = 1, select('#', ...) do
io.write(tostring(select(i, ...)) .. '\t')
end
io.write '\n'
end
...
उपयोग की आसानी के लिए एक तालिका में पैक किया जा सकता है, {...}
का उपयोग करके। यह तालिका के अनुक्रमिक भाग में सभी तर्कों को रखता है।
table.pack(...)
उपयोग वैरग लिस्ट को टेबल में पैक करने के लिए भी किया जा सकता है। table.pack(...)
का लाभ यह है कि यह लौटे हुए तालिका के n
क्षेत्र को select('#', ...)
मान select('#', ...)
। यह महत्वपूर्ण है यदि आपकी तर्क सूची में निल्स हो सकते हैं (नीचे टिप्पणी अनुभाग देखें)।
function my_tablepack(...)
local t = {...}
t.n = select('#', ...)
return t
end
वार्ग सूची को फ़ंक्शंस से भी लौटाया जा सकता है। परिणाम कई रिटर्न है।
function all_or_none(...)
local t = table.pack(...)
for i = 1, t.n do
if not t[i] then
return -- return none
end
end
return ... -- return all
end
उन्नत उपयोग
जैसा कि बुनियादी उदाहरणों में कहा गया है, आपके पास चर बाध्य तर्क और चर तर्क सूची ( ...
) हो सकती है। आप इस तथ्य का उपयोग एक सूची से अलग करने के लिए कर सकते हैं जैसा कि आप अन्य भाषाओं (जैसे हास्केल) में करेंगे। नीचे foldr()
का एक कार्यान्वयन है जो foldr()
लाभ उठाता है। प्रत्येक पुनरावर्ती कॉल vararg सूची के प्रमुख को x
बांधता है, और शेष सूची को पुनरावर्ती कॉल में भेजता है। यह सूची को तब तक नष्ट कर देता है जब तक कि केवल एक तर्क ( select('#', ...) == 0
) न हो। उसके बाद, प्रत्येक मान को पहले आकलित परिणाम के साथ फ़ंक्शन तर्क f
लागू किया जाता है।
function foldr(f, ...)
if select('#', ...) < 2 then return ... end
local function helper(x, ...)
if select('#', ...) == 0 then
return x
end
return f(x, helper(...))
end
return helper(...)
end
function sum(a, b)
return a + b
end
foldr(sum, 1, 2, 3, 4)
--> 10
आप अन्य प्रोग्रामिंग परिभाषाएँ प्राप्त कर सकते हैं जो इस प्रोग्रामिंग शैली को यहाँ अंक # 8 में अंक # 8 के माध्यम से प्राप्त करते हैं।
लुआ का एकमात्र मुहावरेदार डेटा संरचना तालिका है। तालिका लंबाई ऑपरेटर अपरिभाषित है अगर एक क्रम में कहीं भी nil
s स्थित हैं। तालिकाओं के विपरीत, वैरग सूची में स्पष्ट nil
s का सम्मान किया गया है जैसा कि मूल उदाहरणों और टिप्पणियों अनुभाग में कहा गया है (कृपया उस अनुभाग को पढ़ें यदि आपने अभी तक नहीं किया है)। थोड़े से काम से वेरग लिस्ट में म्यूटेशन के अलावा हर ऑपरेशन एक टेबल हो सकता है। यह वार्ग सूची को अपरिवर्तनीय टुपल्स को लागू करने के लिए एक अच्छा उम्मीदवार बनाता है।
function tuple(...)
-- packages a vararg list into an easily passable value
local co = coroutine.wrap(function(...)
coroutine.yield()
while true do
coroutine.yield(...)
end
end)
co(...)
return co
end
local t = tuple((function() return 1, 2, nil, 4, 5 end)())
print(t()) --> 1 2 nil 4 5 | easily unpack for multiple args
local a, b, d = t() --> a = 1, b = 2, c = nil | destructure the tuple
print((select(4, t()))) --> 4 | index the tuple
print(select('#', t())) --> 5 | find the tuple arity (nil respecting)
local function change_index(tpl, i, v)
-- sets a value at an index in a tuple (non-mutating)
local function helper(n, x, ...)
if select('#', ...) == 0 then
if n == i then
return v
else
return x
end
else
if n == i then
return v, helper(n+1, ...)
else
return x, helper(n+1, ...)
end
end
end
return tuple(helper(1, tpl()))
end
local n = change_index(t, 3, 3)
print(t()) --> 1 2 nil 4 5
print(n()) --> 1 2 3 4 5
ऊपर और तालिकाओं के बीच मुख्य अंतर यह है कि टेबल परस्पर हैं और पॉइंटर शब्दार्थ हैं, जहां ट्यूपल में वे गुण नहीं हैं। इसके अतिरिक्त, टुपल्स स्पष्ट nil
s धारण कर सकते हैं और कभी भी अपरिभाषित लंबाई ऑपरेशन नहीं कर सकते हैं।