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


120

ठीक है तो मैं सिर्फ 7.3 को Xcode अपडेट करता हूं और अब मुझे यह चेतावनी मिली है:

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

इस फ़ंक्शन में var का उपयोग करने की आवश्यकता होने पर इसे कैसे ठीक करें:

public func getQuestionList(var language: String) -> NSArray {
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

6
कैसे के बारे मेंpublic func getQuestionList(inout language: String) -> NSArray
TotoroTotoro

2
नहीं, यह एक उपयुक्त प्रतिस्थापन नहीं है। ओपी शायद getQuestionकोई साइड इफेक्ट नहीं करना चाहता है।
बॉलपॉइंटबैन

5
मुझे ईमानदारी से पता नहीं है कि वे इसे हटाने पर भी विचार क्यों करेंगे। यह उन विशेषताओं में से एक थी, जिसने तेजी से कमाल किया!
डैनी ब्रावो

इसे कभी खुद इस्तेमाल न करें और उपद्रव को न समझें।
माइक टैवर्न

@MikeTaverne (देर से जवाब) निम्नलिखित फ़ंक्शन पर विचार करें func foo(_ bar: int) { /*use bar*/ bar+=1; foo(bar); }:। यह बिना var params के असंभव है। आपको या तो फ़ंक्शन के भीतर एक अलग संस्करण बनाने और मान की प्रतिलिपि बनाने की आवश्यकता है, या इनम को इनऑउट के रूप में चिह्नित करना है। पूर्व धीमा है, बाद वाला अपरिभाषित व्यवहार का कारण बनता है। कई एल्गोरिदम इस तरह की पुनरावृत्ति का उपयोग करते हैं।
केविन

जवाबों:


82

क्या आपने एक नए संस्करण को निर्दिष्ट करने का प्रयास किया है

public func getQuestionList(language: String) -> NSArray {
    var lang = language
    if self.data.count > 0 {
        if (lang.isEmpty) {
            lang = "NL"
        }
        return self.data.objectForKey("questionList" + lang) as! NSArray
    }

    return NSArray()
}

11
नहीं वास्तव में मुझे क्या लगता है कि ओपी चाहता था
brimstone

6
मैं ओपी के प्रश्न को उसी तरह समझ सकता था जैसे @garana। ओपी अपने प्रश्न में इनटाउट का उपयोग नहीं करते हैं, वे केवल स्थानीय स्तर पर पहले से मौजूद चर को बदलते हैं ।
एरिक आया

11
वास्तव में यह सही समाधान है। कृपया स्विफ्ट इवोल्यूशन समस्या देखें, जिसने इस बदलाव का प्रस्ताव दिया था: github.com/apple/swift-evolution/blob/master/proposals/…
स्कॉट थॉम्पसन

8
@TimVermeulen हर कोई प्रगतिशील भाषा का उपयोग करना चाहता है। Apple हर एक महीने में सिंटैक्स को बदलकर अपनी भाषा को कई तरीकों से विकसित कर सकता है। जैसा कि आप जानते हैं, ऑनलाइन दस्तावेज़ और कोड स्निपेट का एक टन Apple के कारण समाप्त या पुराना हो गया है। डेवलपर्स को इस साइट पर आना पड़ता है क्योंकि इसकी वजह से कई बेवकूफ सवाल बार-बार पूछे जाते हैं। सिंटेक्स शुरुआत से ही ठोस होना चाहिए अगर Apple चाहता है कि अधिक डेवलपर्स उस पर अच्छे हों।
टॉमस्वर

25
Var भाषा = भाषा का उपयोग करें, यदि आप एक और परिवर्तनशील नाम (जो पहली जगह में var पैरामीटर का मुख्य लाभ था) को शुरू नहीं करना चाहते हैं
हैरिस

102

फ़ंक्शन पैरामीटर से Var को हटाने की चर्चा GitHub पर इस सबमिशन के भीतर पूरी तरह से प्रलेखित है: Var Parameters निकालें

उस दस्तावेज़ में आप पाएंगे कि लोग अक्सर varमापदंडों को भ्रमित करते inoutहैं। एक varपैरामीटर का मतलब है कि पैरामीटर फ़ंक्शन के संदर्भ में परिवर्तनशील है, जबकि एक inoutपैरामीटर के साथ रिटर्न के बिंदु पर पैरामीटर का मान फ़ंक्शन के बाहर और कॉलर के संदर्भ में कॉपी किया जाएगा।

इस समस्या को हल करने का सही तरीका varपैरामीटर से निकालना और एक स्थानीय varचर पेश करना है। दिनचर्या के शीर्ष पर पैरा के मान को उस चर में कॉपी करें।


44
मैं इस बदलाव को बिलकुल नहीं समझ पा रहा हूँ, एक परिवर्तनशील स्थानीय संस्करण बनाने के लिए दूसरी पंक्ति लिखने के लिए सिर्फ एक संस्करण के रूप में परम को परिभाषित करने से बेहतर क्यों होगा?
रॉस बारबिश

मेरे लिए यह परिवर्तन अच्छा है क्योंकि यह उन परिस्थितियों को उठा रहा है, जहां मुझे एक स्थानीय चर को लागू करना चाहिए था, लेकिन मैंने नहीं किया क्योंकि मैंने आसान तरीका निकाला और स्वीकार किया (पुराना) इनपुट पैरामीटर को एक var बनाने की स्विफ्ट का सुझाव
dawid

1
मैं इस पर @RossBarbish के साथ हूं। इसलिए ... इसे हटाया जा रहा है क्योंकि आलसी डेवलपर्स इनओट और var मापदंडों के बीच अंतर नहीं कर सकते हैं? Pfff ...
डैनी ब्रावो

1
यह भयानक रूप से अनावश्यक लगता है ..., उन्हें दोनों विकल्प रखने चाहिए थे।
ऑस्कर गोमेज़

1
शायद स्विफ्ट वैसे भी पर्दे के पीछे पैरामीटर का एक स्थानीय चर ओवरटॉप घोषित कर रहा था। अब हमें इसे मैन्युअल रूप से करना होगा। प्रदर्शन में कोई बदलाव नहीं, लेकिन हमने एक सरल अवधारणा के साथ शुरुआती मदद करने के लिए सुविधा खो दी।
मोगेलबस्टर

62

फ़ंक्शन की शुरुआत में बस इस एक पंक्ति को जोड़ें:

var language = language

और आपके बाकी कोड इस तरह से अपरिवर्तित रह सकते हैं:

public func getQuestionList(language: String) -> NSArray {
    var language = language
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

5
अब तक का सबसे अच्छा जवाब। केवल एक लाइन बदलने की आवश्यकता है।
बॉलपॉइंटबैन

लेकिन ऐसा लगता है कि अप्राकृतिक @ जेम्स
asyncwait

1
मुझे लगता है कि यह सबसे अच्छा जवाब है क्योंकि यह एक ही नाम रखता है। इसी तरह की अन्य आम भाषाएं इसे करती हैं।
ईनोस्ट

1
@RiverSatya सीधे पैरामीटर का उपयोग क्यों न करें?
डेक्कन मैककेना

1
वाकई कमाल का सुझाव है। हम इसे स्विफ्टिफ़ में इस तरह से लागू करेंगे :)
क्रूलेक्स

13

बहुत सारे लोग एक inoutपैरामीटर का सुझाव दे रहे हैं , लेकिन यह वास्तव में ऐसा नहीं है कि वे किसके लिए डिज़ाइन किए गए हैं। इसके अलावा, यह फ़ंक्शन को एक letस्थिर के साथ कॉल करने की अनुमति नहीं देता है, न ही एक स्ट्रिंग शाब्दिक के साथ। आप फ़ंक्शन हस्ताक्षर में डिफ़ॉल्ट मान क्यों नहीं जोड़ते हैं?

public func getQuestionList(language language: String = "NL") -> NSArray {
    if data.count > 0 {
        return data.objectForKey("questionList" + language) as! NSArray
    } else {
        return NSArray()
    }
}

getQuestionListयदि आप डिफ़ॉल्ट भाषा चाहते हैं, तो रिक्त स्ट्रिंग के साथ कॉल न करना सुनिश्चित करें , लेकिन बस पैरामीटर छोड़ दें:

let list = getQuestionList() // uses the default "NL" language

3
मुझे यह भी समझ में नहीं आता है कि जब ओपी शुरुआत में भी इसका इस्तेमाल नहीं कर रहा था तो हर कोई इनाउट समाधान पर कूद गया था ...
एरिक आया

1
वे मान रहे थे कि var और inout ने एक ही काम किया है।
ryantxr

2

स्विफ्ट 4

public func getQuestionList(language: inout String) -> NSArray {
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

getQuestionList(language: &someString)

कुछ मामलों में, जैसा कि मैंने अनुभव किया है (सरणियों को शामिल करने वाले अधिक जटिल सेटअपों के साथ), विधि के भीतर एक नई संपत्ति का निर्माण करना और उस संपत्ति को उत्परिवर्तित करना हमेशा काम नहीं कर सकता है। उल्लेख नहीं करने के लिए, आप केवल inoutएक पैरामीटर को जोड़ने और &इसके तर्क के बजाय विधि को अव्यवस्थित कर रहे हैं , जो कि इस वाक्यविन्यास के लिए बनाया गया था।



0

मुझे लगता है कि @Harris और @garanda जवाब सबसे अच्छा तरीका है।

वैसे भी आपके मामले में, एक संस्करण की आवश्यकता नहीं है, आप कर सकते हैं:

public func getQuestionList(language: String) -> NSArray {
    if self.data.count > 0 {
        return self.data.objectForKey("questionList" + (language.isEmpty ? "NL" : language)) as! NSArray
    }
    return NSArray()
}

0

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

इन-आउट पैरामीटर

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

आप पैरामीटर्स प्रकार से ठीक पहले इनआउट कीवर्ड डालकर एक इन-आउट पैरामीटर लिखते हैं। एक इन-आउट पैरामीटर का एक मान होता है जिसे फ़ंक्शन में पास किया जाता है, फ़ंक्शन द्वारा संशोधित किया जाता है, और मूल मान को बदलने के लिए फ़ंक्शन से वापस पारित किया जाता है। इन-आउट पैरामीटर और संबंधित संकलक अनुकूलन के व्यवहार की विस्तृत चर्चा के लिए, इन-आउट पैरामीटर देखें।

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

ध्यान दें

इन-आउट पैरामीटर में डिफ़ॉल्ट मान नहीं हो सकते हैं, और वेरिएडिक पैरामीटर को इनऑउट के रूप में चिह्नित नहीं किया जा सकता है।

यहाँ एक फ़ंक्शन का उदाहरण है जिसे swapTwoInts कहा जाता है : ( :), जिसमें दो इन-आउट पूर्णांक पैरामीटर हैं जिन्हें a और b कहा जाता है:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

SwapTwoInts ( : :) फ़ंक्शन बस a में b का मान और a में b का मान स्वैप करता है। फ़ंक्शन अस्थायी स्वैप नामक अस्थायी स्थिरांक में मान को संग्रहीत करके इस स्वैप को निष्पादित करता है, b के a को मान प्रदान करता है, और फिर अस्थायी को b को असाइन करता है।

आप swapTwoInts को कॉल कर सकते हैं : ( :) उनके प्रकारों को स्वैप करने के लिए Int के दो चर प्रकार के साथ कार्य करते हैं। ध्यान दें कि someInt और otherInt के नाम एक स्वप्रेरणा के साथ उपसर्ग किए गए हैं जब वे swapTwoInts ( : :) फ़ंक्शन:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

ऊपर दिए गए उदाहरण से पता चलता है कि someInt और otherInt के मूल मूल्यों को swapTwoInts ( : :) फ़ंक्शन द्वारा संशोधित किया गया है , भले ही वे मूल रूप से फ़ंक्शन के बाहर परिभाषित किए गए हों।

ध्यान दें

इन-आउट पैरामीटर किसी फ़ंक्शन से मान वापस करने के समान नहीं हैं। ऊपर दिए गए swapTwoInts उदाहरण एक रिटर्न प्रकार को परिभाषित नहीं करते हैं या एक मूल्य वापस नहीं करते हैं, लेकिन यह अभी भी कुछInt और SecondInt के मूल्यों को संशोधित करता है। किसी कार्य के लिए इन-आउट पैरामीटर एक वैकल्पिक तरीका है जिससे उसके फ़ंक्शन बॉडी के दायरे से बाहर का प्रभाव पड़ता है।


0

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

private class StringBuilder {
    var buffer: [String] = []

    func append(_ str: String) {
        buffer.append(str)
    }

    func toString() -> String {
        return buffer.joined()
    }
}

मैं केवल उपयोग करता हूं appendऔरjoined सरणी पर विधियों , इसलिए मेरे कोड में न्यूनतम अन्य परिवर्तनों के साथ प्रकार को बदलना आसान था।

कुछ उदाहरण उपयोग:

private func writeMap(map: LevelMap, url: URL) -> Bool {
    let buffer = StringBuilder()

    if !writeHeader(map: map, buffer: buffer) {
        return false
    }
    if !writeFloors(map: map, buffer: buffer) {
        return false
    }

    let content = buffer.toString()
    do {
        try content.write(to: url, atomically: true, encoding: .utf8)
        return true
    } catch {}
    return false
}

private func writeHeader(map: LevelMap, buffer: StringBuilder) -> Bool {
    buffer.append("something here ...\n")
    return true
}

मेरा उत्तर यह है कि यदि आप मूल मूल्य को संशोधित करना चाहते हैं, जैसा कि कॉलर द्वारा संशोधित किया जाना है। यदि आप बस मूल्य को स्थानीय रूप से पुन: असाइन करने में सक्षम होना चाहते थे, लेकिन इससे कॉल करने वाले को प्रभावित नहीं किया गया है, तो इससे संबंधित अन्य उत्तर।
webjprgm
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.