स्विफ्ट मेथड पैरामीटर को म्यूटेबल बनाते हैं?


123

अतिरिक्त चर बनाए बिना मैं इस त्रुटि से कैसे निपट सकता हूं?

func reduceToZero(x:Int) -> Int {
    while (x != 0) {
        x = x-1            // ERROR: cannot assign to 'let' value 'x'
    }
    return x
}

मैं केवल x का मान संग्रहीत करने के लिए अतिरिक्त चर नहीं बनाना चाहता। क्या ऐसा करना संभव है जो मैं चाहता हूं?


3
नीचे दिए गए अद्यतन उत्तर देखें, स्विफ्ट 3 ने आपके स्वीकृत उत्तर को हटा दिया है।
अची

जवाबों:


191

जैसा कि अन्य उत्तरों में कहा गया है, स्विफ्ट 3 के रूप में एक वेरिएबल से पहले वाले वर्जन को हटा दिया गया है। हालांकि अन्य उत्तरों में नहीं कहा गया है कि inoutपैरामीटर घोषित करने की क्षमता है । सोचो: एक सूचक में गुजर रहा है।

func reduceToZero(_ x: inout Int) {
    while (x != 0) {
        x = x-1     
    }
}

var a = 3
reduceToZero(&a)
print(a) // will print '0'

यह पुनरावृत्ति में विशेष रूप से उपयोगी हो सकता है।

Apple के inoutघोषणा संबंधी दिशा-निर्देश यहां देखे जा सकते हैं


2
आपका बहुत बहुत धन्यवाद!!!! मैं यहाँ एक पुनरावृत्ति प्रश्न पर फंस गया हूँ। तुमने मेरी जान बचाई।
JW.ZG

2
इसे सावधानी के साथ उपयोग करना चाहिए क्योंकि यह फ़ंक्शन स्कोप के बाहर चर को संशोधित करता है। आदर्श रूप से आप फ़ंक्शन के अंदर आपके द्वारा बदले गए मूल्य को स्पष्ट रूप से वापस करना चाहते हैं।
क्रिस गनवार्डन

2
inoutकीवर्ड को पैरामीटर नाम और पैरामीटर प्रकार के बीच रखा जाना चाहिए: func reduceToZero(x: inout Int) वर्तमान स्विफ्ट 3 संस्करण में।
अगस्टी सेंचेज

सिवाय इसके के लिए बंद करने के लिए काम करने के लिए प्रतीत नहीं होता है क्योंकि स्पष्ट रूप से केवल मूल्य द्वारा inout मापदंडों पर कब्जा (कम से कम त्रुटि संदेश Xcode मुझे देता है)। मैं इस मामले में @GeRyCh समाधान का उपयोग करता हूं।
वूच्रान

धन्यवाद। यह अब के लिए काम किया है, लेकिन सी में संकेत का उपयोग कर की तरह यह एक और स्विफ्ट संस्करण बच जाएगा?
कृष्णा वेदुला

45

'var' पैरामीटर को हटा दिया गया है और स्विफ्ट 3 में हटा दिया जाएगा। इसलिए नए पैरामीटर को असाइन करना अब सबसे अच्छा तरीका लगता है:

func reduceToZero(x:Int) -> Int {
    var x = x
    while (x != 0) {
        x = x-1            
    }
    return x
}

जैसा कि यहां बताया गया है: 'var' पैरामीटर को हटा दिया गया है और स्विफ्ट 3 में हटा दिया जाएगा


1
इस मामले में, क्या यह वास्तव xमें नए में कॉपी करता है var x? या स्विफ्ट उससे ज्यादा कुशल कुछ कर रही है?
गेंकी

3
यह काम करता है और मैं क्या करता हूं, लेकिन यह बहुत अजीब लगता है।
wcochran

1
@Gomfucius स्विफ्ट 3.1 गाइड में इस बारे में एक शब्द भी नहीं। इस मामले में ( xरजिस्टर में फिट बैठता है) लगभग कोई लागत नहीं है। यदि xसरणी, संरचना, या ऑब्जेक्ट जो उत्परिवर्तित है, तो एक प्रतिलिपि लगभग निश्चित रूप से प्रदर्शन करने की आवश्यकता है (जब तक कि ऑप्टिमाइज़र इनलाइन का विश्लेषण नहीं कर सकता है और इसे अन्य नाम दे सकता है)।
wcochran

1
@wcochran यह एक साफ सुथरी चाल है, लेकिन वास्तव में कुछ खास नहीं चल रहा है। यह बस एक स्थानीय var कॉपी के साथ एक इनपुट पैरामीटर ग्रहण कर रहा है। ओपी की स्थिति में यह varargs के लिए एक बेहतर प्रतिस्थापन है inoutजिसके उपयोग से अनपेक्षित दुष्परिणाम, esp हो सकते हैं। अगर var एक पॉइंटर था।
इकलौता

45

स्विफ्ट 1 और 2 के लिए (स्विफ्ट 3 के लिए इनआइटी पैरामीटर का उपयोग करके अची द्वारा उत्तर देखें): स्विफ्ट में एक फ़ंक्शन का तर्क letडिफ़ॉल्ट रूप से है, इसलिए इसे बदल दें varयदि आपको मूल्य को बदलने की आवश्यकता है अर्थात,

func reduceToZero(var x:Int) -> Int {
    while (x != 0) {
        x = x-1     
    }
    return x
}

2
क्यों इस जवाब को मतदान नरक की तरह है? अन्य उत्तर को इस से पहले रखा गया था, और इसमें एक से अधिक जानकारी शामिल है।
क्रिस्चियन

16
/! \ Var का उपयोग पैरामीटर में पारित चर की एक प्रति बनाएगा। इसलिए इसे संशोधित करने से मूल मूल्य में बदलाव नहीं होगा। इसके अलावा varपैरामीटर्स के नए स्विफ्ट संस्करणों के प्रति github.com/apple/swift-evolution/blob/master/proposals/…
Matthieu Riegler

17
var paremeter में var कीवर्ड को स्विफ्ट 3 में चित्रित किया जाएगा।
बून

4
मुझे लगता है कि स्विफ्ट 3 के साथ, हम अब ऐसा नहीं कर पाएंगे। हमें सरणी की एक परिवर्तनशील प्रतिलिपि बनानी होगी और उस संशोधित सरणी को वापस करना होगा।
C0D3

यह उत्तर सही उत्तर है: stackoverflow.com/questions/24077880/…
achi

14

परिवर्तनशील सरणी सूचक पास करने के लिए Swift3 उत्तर।

समारोह:

func foo(array: inout Array<Int>) {
    array.append(1)
}

कार्य करने के लिए कॉल करें:

var a = Array<Int>()
foo(array:&a)

ईमानदारी से, मुझे यकीन नहीं है कि यह सही है क्योंकि स्विफ्ट मैदान कभी-कभी बदल रहा है। मैंने फ़ंक्शन के अंदर var array = array करने से बेहतर समझा क्योंकि यह एक प्रतिलिपि बनाता है (और वास्तव में मूल सरणी संरचना को प्रभावित नहीं करता है)? क्या पूर्वोक्त संस्करण दृष्टिकोण के लिए एक बेहतर डिजाइन दृष्टिकोण है और फिर नए उत्परिवर्तित सरणी को वापस करना है?
जॉश

7

स्विफ्ट में आप varफ़ंक्शन घोषणा में परिवर्तनशील नाम से पहले कीवर्ड जोड़ते हैं :

func reduceToZero(var x:Int) -> Int { // notice the "var" keyword
    while (x != 0) {
        x = x-1            
    }
    return x
}

स्विफ्ट पुस्तक के "फ़ंक्शंस" अध्याय में पृष्ठ पर "कॉन्स्टेंट और वैरिएबल पैरामीटर्स" के उपखंड को देखें (iBook का पृष्ठ 210 जैसा कि आज है)।


7
'var' मापदंडों को हटा दिया गया है और स्विफ्ट 3 में हटा दिया जाएगा
Regis St-Gelais

1
स्विफ्ट 4 और नए के लिए मान्य नहीं है।
ilkayaktas

0

ऐसे कुछ मामले हैं जहां हम उपयोग करने के लिए नहीं हैं inout

हम इस तरह से कुछ का उपयोग कर सकते हैं यदि आप चाहते हैं कि परिवर्तन / गुंजाइश केवल फ़ंक्शन के अंदर हो:

func manipulateData(a: Int) -> Int {
    var a = a
    // ...
}

0

कार्यात्मक प्रोग्रामिंग के साथ Swift5 का उपयोग कर समाधान ...

func reduceToZeroFP(x:Int) -> Int {
    x == 0 ? x : reduceToZeroFP(x: x - 1)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.