जवाबों:
Lua 5.2 में गोटो का उपयोग करना सबसे अच्छा उपाय है:
-- prints odd numbers in [|1,10|]
for i=1,10 do
if i % 2 == 0 then goto continue end
print(i)
::continue::
end
यह संस्करण 2.0.1 के बाद से LuaJIT में समर्थित है
continue
एक दिन शामिल होंगे। goto
प्रतिस्थापन बहुत अच्छी लग रही है और अधिक लाइनों की जरूरत नहीं है। इसके अलावा, यदि आप एक से अधिक लूप एक फ़ंक्शन में ऐसा कर रहे हैं, तो यह परेशानी पैदा नहीं करेगा, दोनों के साथ ::continue::
? प्रति पाश नाम बनाना एक अच्छी बात की तरह नहीं लगता है।
जिस तरह से भाषा लेक्सिकल स्कोप का प्रबंधन करती है वह दोनों के साथ मुद्दों को पैदा करती है goto
और continue
। उदाहरण के लिए,
local a=0
repeat
if f() then
a=1 --change outer a
end
local a=f() -- inner a
until a==0 -- test inner a
local a
लूप बॉडी के अंदर की घोषणा नामांकित बाहरी चर को मास्क करती है a
, और उस स्थानीय का दायरा until
विवरण की स्थिति में फैला हुआ है, इसलिए स्थिति अंतरतम का परीक्षण कर रही है a
।
यदि continue
अस्तित्व में है, तो यह केवल शब्दांश के दायरे में आने के बाद इसे केवल वैध होने के लिए प्रतिबंधित किया जाना चाहिए। यह उपयोगकर्ता के लिए दस्तावेज़ और कंपाइलर में लागू करने के लिए एक कठिन स्थिति है। इस मुद्दे के चारों ओर विभिन्न प्रस्तावों पर चर्चा की गई है, जिसमें लूप continue
की repeat ... until
शैली के साथ अस्वीकार करने का सरल उत्तर भी शामिल है । अब तक, किसी को भी भाषा में शामिल करने के लिए पर्याप्त सम्मोहक उपयोग का मामला नहीं रहा है।
आस-पास का काम आम तौर पर उस स्थिति को उलटने के लिए होता है, जो continue
निष्पादित होने का कारण बनती है , और शेष लूप बॉडी को उस स्थिति में एकत्रित करता है। तो, निम्नलिखित लूप
-- not valid Lua 5.1 (or 5.2)
for k,v in pairs(t) do
if isstring(k) then continue end
-- do something to t[k] when k is not a string
end
लिखा जा सकता है
-- valid Lua 5.1 (or 5.2)
for k,v in pairs(t) do
if not isstring(k) then
-- do something to t[k] when k is not a string
end
end
यह पर्याप्त रूप से स्पष्ट है, और आमतौर पर एक बोझ नहीं है जब तक कि आपके पास लूप ऑपरेशन को नियंत्रित करने वाले विस्तृत culls की एक श्रृंखला न हो।
until...
।
goto
Lua 5.2 में आने से पहले Lua समुदाय में इसकी बहुत चर्चा हुई थी । स्वाभाविक रूप से, goto
एक ही मुद्दा है। उन्होंने अंततः निर्णय लिया कि जो भी रनटाइम और / या कोड जनरेशन की लागतों से रक्षा के लिए थे, वे एक लचीले होने के लाभों के लायक थे goto
जो कि दोनों continue
और बहु-स्तर का अनुकरण करने के लिए उपयोग किया जा सकता है break
। आपको विवरण प्राप्त करने के लिए संबंधित थ्रेड्स के लिए Lua सूची संग्रह खोजना होगा । चूंकि उन्होंने परिचय दिया था goto
, इसलिए यह स्पष्ट नहीं था।
local
कंपाइलर-केवल निर्देश है - इससे कोई फर्क नहीं पड़ता कि रनटाइम इंसट्रक्शन क्या हैं local
और वेरिएबल उपयोग के लिए - समान स्कूपिंग व्यवहार को बनाए रखने के लिए आपको कंपाइलर में कुछ भी बदलने की आवश्यकता नहीं है। हां, यह इतना स्पष्ट नहीं हो सकता है और कुछ अतिरिक्त प्रलेखन की आवश्यकता है, लेकिन, फिर से दोहराने के लिए, इसे संकलक में शून्य परिवर्तन की आवश्यकता होती है। repeat do break end until true
मेरे जवाब में उदाहरण पहले से ही बिल्कुल बायटेकोड उत्पन्न करता है जो संकलक जारी रखेगा, केवल अंतर यह है कि इसके साथ continue
आपको इसका उपयोग करने के लिए बदसूरत अतिरिक्त सिंटैक्स की आवश्यकता नहीं होगी।
do{int i=0;}while (i == 0);
विफल, या C ++ में बराबर पर विचार करें : do int i=0;while (i==0);
भी विफल रहता है ("इस दायरे में घोषित नहीं किया गया था")। बहुत देर हो गई कि अब लुआ में, दुर्भाग्य से।
आप लूप बॉडी को अतिरिक्त रूप से लपेट सकते हैं repeat until true
और फिर do break end
जारी रखने के प्रभाव के लिए अंदर का उपयोग कर सकते हैं । स्वाभाविक रूप से, यदि आपको वास्तव break
में लूप से बाहर निकलने का इरादा है, तो आपको अतिरिक्त झंडे लगाने की आवश्यकता होगी।
यह हर बार 5, 1, 2 और 3 की छपाई करेगा।
for idx = 1, 5 do
repeat
print(1)
print(2)
print(3)
do break end -- goes to next iteration of for
print(4)
print(5)
until true
end
यह निर्माण भी JMP
Lua bytecode में शाब्दिक एक ओपोड के लिए अनुवाद करता है!
$ luac -l continue.lua
main <continue.lua:0,0> (22 instructions, 88 bytes at 0x23c9530)
0+ params, 6 slots, 0 upvalues, 4 locals, 6 constants, 0 functions
1 [1] LOADK 0 -1 ; 1
2 [1] LOADK 1 -2 ; 3
3 [1] LOADK 2 -1 ; 1
4 [1] FORPREP 0 16 ; to 21
5 [3] GETGLOBAL 4 -3 ; print
6 [3] LOADK 5 -1 ; 1
7 [3] CALL 4 2 1
8 [4] GETGLOBAL 4 -3 ; print
9 [4] LOADK 5 -4 ; 2
10 [4] CALL 4 2 1
11 [5] GETGLOBAL 4 -3 ; print
12 [5] LOADK 5 -2 ; 3
13 [5] CALL 4 2 1
14 [6] JMP 6 ; to 21 -- Here it is! If you remove do break end from code, result will only differ by this single line.
15 [7] GETGLOBAL 4 -3 ; print
16 [7] LOADK 5 -5 ; 4
17 [7] CALL 4 2 1
18 [8] GETGLOBAL 4 -3 ; print
19 [8] LOADK 5 -6 ; 5
20 [8] CALL 4 2 1
21 [1] FORLOOP 0 -17 ; to 5
22 [10] RETURN 0 1
luac
SO पर आउटपुट प्रदान करने के लिए देखकर अच्छा लगा ! अच्छी तरह से
"जारी" के साथ हमारी मुख्य चिंता यह है कि कई अन्य नियंत्रण संरचनाएं हैं (हमारे विचार में) "जारी" के रूप में कम या ज्यादा महत्वपूर्ण हैं और यहां तक कि इसे प्रतिस्थापित भी कर सकते हैं। (जैसे, लेबल के साथ तोड़ना [जैसा कि जावा में] या इससे भी अधिक सामान्य गोटो।) "जारी" अन्य नियंत्रण-संरचना तंत्रों की तुलना में अधिक विशेष नहीं लगता है, सिवाय इसके कि यह अधिक भाषाओं में मौजूद है। (पर्ल के पास वास्तव में दो "जारी" बयान हैं, "अगले" और "फिर से करें"। दोनों उपयोगी हैं।)
continue
, क्षमा करें।"
पहले भाग का उत्तर अक्सर पूछे जाने वाले प्रश्न के रूप में दिया जाता है।
वर्कअराउंड के लिए, आप एक फंक्शन में लूप के शरीर को लपेट सकते हैं और return
उसी से, जैसे
-- Print the odd numbers from 1 to 99
for a = 1, 99 do
(function()
if a % 2 == 0 then
return
end
print(a)
end)()
end
या यदि आप दोनों break
और continue
कार्यक्षमता चाहते हैं , तो स्थानीय फ़ंक्शन का परीक्षण करें, जैसे
local a = 1
while (function()
if a > 99 then
return false; -- break
end
if a % 2 == 0 then
return true; -- continue
end
print(a)
return true; -- continue
end)() do
a = a + 1
end
collectgarbage("count")
अपने सरल 100 प्रयासों के बाद भी जांच करें और फिर हम बात करेंगे। इस तरह के "समय से पहले" अनुकूलन ने पिछले हफ्ते हर मिनट एक रिबूट परियोजना को रिबूट करने से बचा लिया।
मैंने पहले कभी लुआ का उपयोग नहीं किया है, लेकिन मैंने इसे गुगली दिया और इस के साथ आया:
प्रश्न 1.26 की जाँच करें ।
यह एक आम शिकायत है। लुआ लेखकों ने महसूस किया कि जारी रखना संभव नए नियंत्रण प्रवाह तंत्रों में से एक था (तथ्य यह है कि यह दोहराने के दायरे के नियमों के साथ काम नहीं कर सकता है / जब तक कि एक माध्यमिक कारक नहीं था।)
Lua 5.2 में, एक गोटो स्टेटमेंट है जिसे आसानी से एक ही काम करने के लिए इस्तेमाल किया जा सकता है।
हमने कई बार इस परिदृश्य का सामना किया और हम जारी रखने के लिए एक ध्वज का उपयोग करते हैं। हम गोटो बयानों के इस्तेमाल से भी बचने की कोशिश करते हैं।
उदाहरण: कोड का इरादा i = 1 से i = 10 को छोड़कर i = 3 से स्टेटमेंट प्रिंट करना है। इसके अलावा यह "लूप स्टार्ट", लूप एंड "," इफ स्टार्ट ", और" इफ एंड "को अन्य नेस्टेड स्टेटमेंट्स को अनुकरण करने के लिए प्रिंट करता है जो आपके कोड में मौजूद हैं।
size = 10
for i=1, size do
print("loop start")
if whatever then
print("if start")
if (i == 3) then
print("i is 3")
--continue
end
print(j)
print("if end")
end
print("loop end")
end
एक परीक्षण ध्वज के साथ लूप के अंतिम दायरे तक सभी शेष कथनों को संलग्न करके प्राप्त किया जाता है।
size = 10
for i=1, size do
print("loop start")
local continue = false; -- initialize flag at the start of the loop
if whatever then
print("if start")
if (i == 3) then
print("i is 3")
continue = true
end
if continue==false then -- test flag
print(j)
print("if end")
end
end
if (continue==false) then -- test flag
print("loop end")
end
end
मैं यह नहीं कह रहा हूं कि यह सबसे अच्छा तरीका है लेकिन यह हमारे लिए पूरी तरह से काम करता है।
लुआ हल्की पटकथा वाली भाषा है जो संभव के रूप में छोटी करना चाहती है। उदाहरण के लिए, कई यूनिरी ऑपरेशन जैसे कि प्री / पोस्ट इंक्रीमेंट उपलब्ध नहीं है
जारी रखने के बजाय, आप गोटो का उपयोग कर सकते हैं
arr = {1,2,3,45,6,7,8}
for key,val in ipairs(arr) do
if val > 6 then
goto skip_to_next
end
# perform some calculation
::skip_to_next::
end
Inverting के साथ फिर से, आप बस निम्नलिखित कोड का उपयोग कर सकते हैं:
for k,v in pairs(t) do
if not isstring(k) then
-- do something to t[k] when k is not a string
end
क्योंकि यह अनावश्यक है। वहाँ बहुत कम स्थितियाँ हैं जहाँ एक देव को इसकी आवश्यकता होगी।
ए) जब आपके पास एक बहुत ही सरल लूप होता है, तो 1- या 2-लाइनर कहें, तो आप बस लूप की स्थिति को बदल सकते हैं और यह अभी भी बहुत पठनीय है।
बी) जब आप सरल प्रक्रियात्मक कोड लिख रहे हैं (उर्फ। हमने पिछली शताब्दी में कोड कैसे लिखा था), तो आपको संरचित प्रोग्रामिंग (उर्फ) भी लागू करना चाहिए। हमने पिछली शताब्दी में बेहतर कोड कैसे लिखा था)
ग) यदि आप ऑब्जेक्ट-ओरिएंटेड कोड लिख रहे हैं, तो आपके लूप बॉडी में एक या दो विधि कॉलों से अधिक नहीं होना चाहिए जब तक कि इसे एक या दो-लाइनर में व्यक्त नहीं किया जा सकता है (जिस स्थिति में, ए देखें)
डी) यदि आप कार्यात्मक कोड लिख रहे हैं, तो बस अगले पुनरावृत्ति के लिए एक सादा पूंछ-कॉल लौटाएं।
केवल तभी जब आप किसी continue
कीवर्ड का उपयोग करना चाहते हैं यदि आप Lua को कोड करना चाहते हैं जैसे कि यह अजगर है, जो कि यह अभी नहीं है।
जब तक ए) लागू नहीं होता है, उस स्थिति में किसी भी कार्य-प्रणाली की आवश्यकता नहीं है, आपको संरचित, ऑब्जेक्ट-ओरिएंटेड या कार्यात्मक प्रोग्रामिंग करना चाहिए। वे प्रतिमान हैं जिन्हें Lua के लिए बनाया गया था, इसलिए यदि आप अपने पैटर्न से बचने के लिए अपने रास्ते से बाहर जाते हैं तो आप भाषा के खिलाफ लड़ेंगे।
कुछ स्पष्टीकरण:
¹ लुआ एक बहुत ही न्यूनतम भाषा है। यह कुछ सुविधाओं के रूप में इसे दूर करने की कोशिश कर सकता है, और एक continue
बयान उस अर्थ में एक आवश्यक विशेषता नहीं है।
मुझे लगता है कि इस 2019 साक्षात्कार में रॉबर्टो इयरुसिलेम्स्की द्वारा अतिसूक्ष्मवाद के इस दर्शन को अच्छी तरह से कैप्चर किया गया है :
वह जोड़ें और वह और वह, उसे बाहर रखें, और अंत में हम समझते हैं कि अंतिम निष्कर्ष ज्यादातर लोगों को संतुष्ट नहीं करेगा और हम सभी विकल्पों को नहीं डालेंगे जो हर कोई चाहता है, इसलिए हम कुछ भी नहीं डालते हैं। अंत में, सख्त मोड एक उचित समझौता है।
Other अन्य भाषाओं से लुआ में आने वाले प्रोग्रामरों का एक बड़ा समूह प्रतीत होता है क्योंकि जो भी कार्यक्रम वे उपयोग करने के लिए स्क्रिप्ट के लिए प्रयास कर रहे हैं, और उनमें से बहुत से लोग अपनी भाषा के अलावा कुछ भी लिखना नहीं चाहते हैं। पसंद, जो कई सवालों की ओर ले जाती है जैसे "Lua में X सुविधा क्यों नहीं है?"
मैत्ज़ ने हाल के एक साक्षात्कार में रूबी के साथ इसी तरह की स्थिति का वर्णन किया :
सबसे लोकप्रिय प्रश्न यह है: "मैं भाषा X समुदाय से हूं; क्या आप X से रूबी के लिए भाषा की विशेषता का परिचय नहीं दे सकते?", या उसके बाद कुछ। और इन अनुरोधों का मेरा सामान्य उत्तर है ... "नहीं, मैं ऐसा नहीं करूंगा", क्योंकि हमारे पास विभिन्न भाषा डिजाइन और विभिन्न भाषा विकास नीतियां हैं।
This इसके आसपास अपना रास्ता हैक करने के कुछ तरीके हैं; कुछ उपयोगकर्ताओं ने उपयोग करने का सुझाव दिया है goto
, जो कि ज्यादातर मामलों में काफी अच्छा है, लेकिन बहुत जल्दी बदसूरत हो जाता है और नेस्टेड छोरों के साथ पूरी तरह से टूट जाता है। goto
जब भी आप अपना कोड किसी और को दिखाते हैं तो एस का उपयोग करने से आपके ऊपर फेंकी गई एसआईसीपी की एक प्रति होने का खतरा होता है।
continue
एक सुविधाजनक सुविधा हो सकती है, लेकिन यह जरूरी नहीं है । बहुत से लोग बिना इसके ठीक लुआ का उपयोग करते हैं, इसलिए वास्तव में इसके लिए ऐसा कोई मामला नहीं है जो एक साफ सुथरी विशेषता के अलावा कुछ भी हो जो किसी भी प्रोग्रामिंग भाषा के लिए आवश्यक नहीं है।
goto
बयान मिला, जिसे जारी रखने के लिए इस्तेमाल किया जा सकता है। नीचे दिए गए जवाब देखें।