डिफॉल्ट पैरामीटर वैल्यू फंक्शन के किसी भी पैरामीटर के लिए दी जा सकती है। इसके लिए पैरामीटर लिस्ट में उस पैरामीटर के टाइप एनोटेशन के बाद एक वैल्यू असाइन की जाती है। जब डिफॉल्ट वैल्यू दी गई हो, तो फंक्शन को कॉल करते समय कॉल करने वाला उस पैरामीटर को छोड़ सकता है, और उसकी जगह डिफॉल्ट वैल्यू इस्तेमाल की जाती है।
func greeting(name: String = "guest", duration: Int = 2) -> String {
"Welcome, \(name). Enjoy your \(duration) night stay."
}
greeting(name: "Bobo", duration: 7)
// Returns "Welcome, Bobo. Enjoy your 7 night stay."
greeting(duration: 3)
// Returns "Welcome, guest. Enjoy your 3 night stay."
greeting(name: "Wynona")
// Returns "Welcome, Wynona. Enjoy your 2 night stay."
greeting()
// Returns "Welcome, guest. Enjoy your 2 night stay."
वेरिएडिक पैरामीटर की मदद से कोई फंक्शन एक ही पैरामीटर के लिए किसी तय टाइप की शून्य या अधिक वैल्यू ले सकता है।
वेरिएडिक पैरामीटर बनाने के लिए पैरामीटर के टाइप एनोटेशन के आगे तीन बिंदु (...) लगाइए।
फंक्शन के अंदर Swift इन वैल्यू को बताए गए टाइप के ऐरे के रूप में उपलब्ध कराता है:
import Foundation
func geometricMean(_ numbers: Double...) -> Double {
var total = 1.0
for number in numbers {
total *= number
}
return pow(total, 1.0 / Double(numbers.count))
}
let result = geometricMean(1, 2, 3, 4, 5)
// result is 2.605171084697352
अगर किसी फंक्शन में वेरिएडिक पैरामीटर के बाद और पैरामीटर भी हों, तो वेरिएडिक पैरामीटर के बाद आने वाले पहले पैरामीटर का आर्गुमेंट लेबल साफ़ तौर पर लिखा होना ज़रूरी है, ताकि Swift को पता चले कि वेरिएडिक आर्गुमेंट की सूची कहाँ खत्म होती है।
किसी फंक्शन के अंदर पैरामीटर को वेरिएबल नहीं, कॉन्स्टेंट माना जाता है। पैरामीटर की वैल्यू बदलने की कोशिश करने पर कंपाइल के समय एरर मिलती है। अगर किसी फंक्शन को पैरामीटर की वैल्यू बदलनी है, तो उसे इन-आउट पैरामीटर इस्तेमाल करना होगा, ताकि यह साफ़ हो जाए कि वैल्यू बदली जा सकती है।
इन-आउट पैरामीटर इस्तेमाल करने के लिए प्रोग्रामर को तीन बातों का ध्यान रखना होता है:
: और टाइप के नाम के बीच inout कीवर्ड लिखकर इन-आउट पैरामीटर को साफ़ तौर पर चिह्नित करना होता है।& लगाना होता है, जिससे साफ़ हो जाए कि इसे बदला जा सकता है।ऐसा करने पर फंक्शन इन-आउट पैरामीटर की अंदर ही एक कॉपी बनाता है, फंक्शन के अंदर बताए अनुसार उसे बदलता है, और फिर फंक्शन लौटते समय बदली हुई वैल्यू को उसी वेरिएबल में वापस कॉपी कर देता है जो पास की गई थी।
func updateVersion(_ record: inout (version: Int, title: String)) {
record.version += 1
}
var dbRecord = (version: 2, title: "Exercism")
updateVersion(&dbRecord)
// dbRecord is now (3, "Exercism")
इन-आउट पैरामीटर के बारे में दो-एक अतिरिक्त नियम भी ध्यान में रखने चाहिए।
1 इन-आउट पैरामीटर वाले फंक्शन के अंदर उस वेरिएबल को संदर्भित नहीं किया जा सकता जो इन-आउट पैरामीटर के रूप में पास किया गया था।
2. एक ही फंक्शन में एक ही वेरिएबल को कई इन-आउट पैरामीटर के रूप में पास नहीं किया जा सकता।
जैसे, `inoutFunc(&mutVar, &mutVar)` लिखने पर कंपाइलर एरर देता है।
Swift में आप दूसरे फंक्शन के अंदर फंक्शन बना सकते हैं। इन्हें नेस्टेड फंक्शन कहते हैं।
नेस्टेड फंक्शन आम तौर पर ऐसे प्राइवेट हेल्पर होते हैं, जो अपने बाहरी फंक्शन के लिए कुछ खास काम करते हैं और बाहरी स्कोप को अव्यवस्थित नहीं करते:
func makeNumber(_ number: Int) -> Int {
func double(_ x: Int) -> Int {
x * 2
}
func increment(_ x: Int) -> Int {
x + 1
}
return number.isMultiple(of: 2) ? increment(double(number)) : double(number)
}
print(makeNumber(3)) // Prints 6
print(makeNumber(4)) // Prints 9
नेस्टेड फंक्शन आम फंक्शन की तरह ही व्यवहार करते हैं, लेकिन इन्हें सिर्फ बाहरी फंक्शन के अंदर ही देखा जा सकता है।
इस अभ्यास में आप अपनी पसंदीदा कुकबुक से बनी शानदार लसान्या पकाने के लिए कुछ और कोड लिखेंगे।
आपके सामने पाँच काम हैं, और सबका संबंध लसान्या पकाने में लगने वाले समय से है।
आप remainingMinutesInOven फंक्शन को बेहतर बनाना चाहते हैं। यह फंक्शन पैरामीटर के रूप में वे बीते हुए मिनट लेता है जितनी देर लसान्या ओवन में रही है, और पिछले काम में तय किए गए अपेक्षित ओवन समय के हिसाब से बताता है कि लसान्या को ओवन में अभी कितने मिनट और रहना है।
पहले आप expectedMinutesInOven नाम की एक स्थिर वैल्यू पर निर्भर थे, जो remainingMinutesInOven फंक्शन के बाहर से आती थी।
इसमें दो दिक्कतें थीं: यह आपकी पसंद के हिसाब से थोड़ा बहुत उलझा हुआ था, और लचीला भी कम था, क्योंकि इससे ओवन का अपेक्षित समय बदलना संभव नहीं था।
इसे साफ-सुथरा बनाने के लिए remainingMinutesInOven फंक्शन बनाइए। यह फंक्शन पैरामीटर के रूप में वे बीते हुए मिनट लेता है जितनी देर लसान्या ओवन में रही है, और साथ ही एक expectedMinutesInOven पैरामीटर भी लेता है, जिसकी वैल्यू पहले से 40 तय है।
आपके फंक्शन को पिछले काम में तय अपेक्षित ओवन समय के हिसाब से बताना चाहिए कि लसान्या को ओवन में अभी कितने मिनट और रहना है।
remainingMinutesInOven(elapsedMinutes: 30)
// Returns 10
remainingMinutesInOven(elapsedMinutes: 30, expectedMinutesInOven: 75)
// Returns 45
पिछले अभ्यास में आपने preparationTimeInMinutes फंक्शन लिखा था, जो पैरामीटर के रूप में लसान्या में डाली गई परतों की संख्या लेता है और बताता है कि लसान्या तैयार करने में आपने कितने मिनट लगाए, यह मानकर कि हर परत तैयार करने में 2 मिनट लगते हैं।
लेकिन यह फंक्शन आपको खास पसंद नहीं है, क्योंकि इस फंक्शन को कॉल करने से पहले आपको अपनी लसान्या की परतें खुद गिननी पड़ती हैं। और इतना सब करने का समय किसके पास है?
अपना काम आसान बनाने के लिए preparationTimeInMinutes नाम का एक फंक्शन लिखिए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं।
फिर यह फंक्शन आपकी लसान्या की परतें गिनकर बताएगा कि तैयारी में कितना समय लगेगा।
preparationTimeInMinutes(layers: "sauce", "noodles")
// Returns 4
preparationTimeInMinutes(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns 24
अपनी लसान्या की परतें लगाना शुरू करने से पहले आप यह पक्का करना चाहते हैं कि आपके सपनों की लसान्या बनाने के लिए आपके पास पर्याप्त सॉस और नूडल्स हों। लसान्या की हर नूडल परत के लिए आपको 3 नूडल्स चाहिए। लसान्या की हर सॉस परत के लिए 0.2 लीटर सॉस चाहिए।
quantities फंक्शन बनाइए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं।
फिर यह फंक्शन तय करेगा कि आपका खाना बनाने के लिए कितने नूडल्स और कितना सॉस चाहिए। नतीजा (noodles: Int, sauce: Double) टाइप के टपल में लौटाना चाहिए।
quantities(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns (noodles: 9, sauce: 0.8)
quantities(layers: "sauce", "noodles", "sauce", "noodles", "meat", "noodles", "mozzarella")
// Returns (noodles: 9, sauce: 0.4)
दुर्भाग्य से, आपके पास जो सॉस है उसका आयतन लीटर की जगह फ्लुइड औंस में लिखा है।
यह जानने के लिए कि आपके पास पर्याप्त सॉस है या नहीं, toOz नाम का एक फंक्शन लिखिए, जो एक इन-आउट टपल पैरामीटर, (noodles: Int, sauce: Double), लेता है और सॉस की मात्रा को फ्लुइड औंस में बदल देता है।
ध्यान रखिए कि एक लीटर में 33.814 फ्लुइड औंस होते हैं।
var amount = (noodles: 9, sauce: 0.8)
toOz(&amount)
amount
// Returns (noodles: 9, sauce: 27.0512)
अंत में, आप जानना चाहते हैं कि अपनी लसान्या के साथ किस तरह की वाइन परोसी जाए।
आपने सुना है कि अगर लसान्या में मोज़रेला, रिकोटा और बेशमेल की परतें मीट और सॉस की परतों से अधिक हों, तो सफेद वाइन परोसनी चाहिए, वरना रेड वाइन।
redWine फंक्शन लिखिए, जो एक वेरिएडिक String पैरामीटर, layers, लेता है, जिसमें आप अपनी लसान्या की अलग-अलग परतें लिखते हैं।
यह फंक्शन पाँच नेस्टेड फंक्शन इस्तेमाल करके लसान्या में मोज़रेला, रिकोटा, बेशमेल, सॉस और मीट की परतों की संख्या निकालेगा, और परतों की संख्याओं की तुलना करके तय करेगा कि रेड वाइन परोसनी चाहिए या नहीं। अगर हाँ, तो यह true लौटाएगा, और अगर नहीं, तो false।
redWine(layers: "sauce", "noodles", "sauce", "meat", "mozzarella", "noodles", "sauce", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns true
redWine(layers: "sauce", "noodles", "béchamel", "meat", "mozzarella", "noodles", "ricotta", "eggplant", "béchamel", "noodles", "sauce", "mozzarella")
// Returns false
Exercism पर साइन अप कीजिए और Swift को 35 कॉन्सेप्ट116 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।