2015-01-31 11 views
6

जब सामान्य रूप से उपयोग कर एक के लिए-इन-पाश, काउंटर (इस मामले number में) में एक स्थिर है में प्रत्येक यात्रा:काउंटर के लिए-इन-लूप

for number in 1...10 { 
    // do something 
} 

इसका मतलब यह है मैं number बदल नहीं सकते पाश में:

for number in 1...10 { 
    if number == 5 { 
     ++number 
    } 
} 

// doesn't compile, since the prefix operator '++' can't be performed on the constant 'number' 

वहाँ number एक चर के रूप में घोषित करने के लिए एक रास्ता है, पाश से पहले यह घोषणा करते हुए या के लिए लूप एक सामान्य का उपयोग कर (आरंभीकरण, हालत और वेतन वृद्धि के साथ) के बिना?

+1

संशोधित करना:

क्या आप चाहते हैं (सी-शैली for या while का सहारा के बिना) पाश, अपने बेहतर शर्त के कुछ पुनरावृत्तियों को छोड़ने के लिए है, तो एक जनरेटर है कि प्रासंगिक मूल्यों को छोड़ देता है उपयोग करने के लिए है 'for' के इटरेटर को आमतौर पर खराब कोड माना जाता है। 'इन' के लिए कोई पुनरावर्तक नहीं है, 'संख्या' एक पुनरावर्तक नहीं है। इसका मूल्य लूप को किसी भी तरह से प्रभावित नहीं करता है। – Sulthan

उत्तर

12

समझने के लिए क्यों i म्यूटेबल नहीं हो सकता है यह जानने के लिए कि for…in क्या है। for i in 0..<10 निम्न के संकलक द्वारा विस्तार किया जाता है:

var g = (0..<10).generate() 
while let i = g.next() { 
    // use i 
} 

पाश के आसपास हर बार, i एक ताजी घोषित चर, जनरेटर पर next कॉल करने से अगले परिणाम unwrapping का मूल्य है।

अब, यह while इस तरह लिखा जा सकता है:

while var i = g.next() { 
    // here you _can_ increment i: 
    if i == 5 { ++i } 
} 

लेकिन निश्चित रूप से, यह मदद नहीं होगा - g.next() अभी भी पाश के आसपास एक 5 अगली बार उत्पन्न करने के लिए जा रहा है। शरीर में वृद्धि व्यर्थ थी।

संभावित रूप से इस कारण से for…in उसी लूप काउंटर को घोषित करने के लिए उसी var वाक्यविन्यास का समर्थन नहीं करता है - अगर आपको यह नहीं पता था कि यह कैसे काम करता है तो यह बहुत भ्रमित होगा।

(where के विपरीत, जहां आप देख सकते हैं कि क्या हो रहा है - var कार्यक्षमता कभी-कभी उपयोगी होती है, इसी प्रकार func f(var i) कैसे हो सकता है)।

// iterate over every other integer 
for i in 0.stride(to: 10, by: 2) { print(i) } 

// skip a specific number 
for i in (0..<10).filter({ $0 != 5 }) { print(i) } 

let a = ["one","two","three","four"] 

// ok so this one’s a bit convoluted... 
let everyOther = a.enumerate().filter { $0.0 % 2 == 0 }.map { $0.1 }.lazy 

for s in everyOther { 
    print(s) 
} 
+0

आप बस महान जवाब देते हैं! –

+0

स्विफ्ट 3 में लूप में ... के लिए var की अनुमति देता है। हालांकि, यह प्रत्येक मोड़ पर अधिलेखित है। – Etan

2

उत्तर "नहीं" है, और यह एक अच्छी बात है। अन्यथा, इस तरह एक निहायत उलझनपूर्ण व्यवहार संभव होगा:

for number in 1...10 { 
    if number == 5 { 
     // This does not work 
     number = 5000 
    } 
    println(number) 
} 

किसी एक पाश है कि माना जाता है कि हालांकि 1 से 10, समावेशी की एक श्रृंखला के लिए बाध्य है के उत्पादन में 5000 संख्या को देखने का भ्रम की कल्पना करें।

इसके अलावा, स्विफ्ट 5000 के अगले मूल्य के रूप में क्या उठाएगा? क्या इसे रोकना चाहिए? क्या इसे असाइनमेंट से पहले श्रेणी में अगले नंबर पर जारी रखना चाहिए? क्या इसे ऑफ-ऑफ-रेंज असाइनमेंट पर अपवाद फेंकना चाहिए? इन तीनों विकल्पों में उनके लिए कुछ वैधता है, इसलिए कोई स्पष्ट विजेता नहीं है।

इस तरह की स्थितियों से बचने के लिए, स्विफ्ट डिजाइनरों ने रेंज लूप में लूप वेरिएबल्स को अपरिवर्तनीय बना दिया।

+0

'इन इन' के बारे में सोचने में वास्तव में मददगार है क्योंकि एक पूरी तरह से अलग संरचना है जो लूप के लिए एक आम 'है। 'संख्या' एक पुनरावर्तक नहीं है, यह एक फ़ंक्शन/ब्लॉक का पैरामीटर है जिसे प्रत्येक पुनरावृत्ति में बुलाया जाता है। – Sulthan

संबंधित मुद्दे