किसी Swift फंक्शन सिग्नेचर से अगर सारे नाम और लेबल हटा दिए जाएँ, तो जो बचता है वह उस फंक्शन का टाइप होता है।
func shoppingList(item: String, quantity: Int) -> String {
"You need to buy \(quantity) \(item)."
}
// shoppingList: (String, Int) -> String
func repeater(_ phrase: String, times: Int) -> String {
var result = ""
for _ in 1...times {
result += phrase
}
return result
}
// repeater: (String, Int) -> String
func printString(line: String) {
print(line)
}
// printString: (String) -> ()
ध्यान दीजिए कि पहले दो फंक्शनों के टाइप एक ही हैं, (String, Int) -> String, हालाँकि दोनों के सिग्नेचर अलग हैं और दोनों फंक्शन बहुत अलग तरीके से काम करते हैं। ये दोनों इनपुट में एक String और एक Int लेते हैं और एक String लौटाते हैं। और तीसरे फंक्शन के टाइप से पता चलता है कि फंक्शन के अंदर का कोड भले ही कुछ लौटाता न दिखे, वह वास्तव में अप्रत्यक्ष रूप से () लौटाता है, जो Void टाइप की एकमात्र वैल्यू है।
इन फंक्शन टाइपों का उपयोग Swift में किसी भी दूसरे टाइप की तरह किया जा सकता है। जैसे, इन्हें वेरिएबल या कॉन्स्टेंट घोषित करते समय इस्तेमाल किया जा सकता है। और चूँकि Swift में फंक्शन भी वैल्यू होते हैं, पहले से मौजूद फंक्शनों को इन कॉन्स्टेंट या वेरिएबल में असाइन किया जा सकता है:
var stringAndIntToString: (String, Int) -> String
stringAndIntToString = shoppingList
stringAndIntToString("carrots", 3)
// => "You need to buy 3 carrots."
बाकी वेरिएबल या कॉन्स्टेंट की तरह, आप जो वैल्यू असाइन करते हैं वह सही टाइप की होनी चाहिए:
stringAndIntToString = printShoppingList
// Error: Cannot assign value of type '(String) -> ()' to type '(String, Int) -> String'
फंक्शन टाइपों का उपयोग वहीं किया जा सकता है जहाँ बाकी टाइप किए जा सकते हैं। इसलिए इन्हें पैरामीटर टाइप की तरह भी इस्तेमाल किया जा सकता है, दूसरे फंक्शनों को दिया जा सकता है, और उन फंक्शनों के अंदर से कॉल किया जा सकता है।
func apply3(to str: String, function f: (String, Int) -> String) -> String {
f(str,3)
}
// apply3: ([String], (String, Int) -> String) -> [String]
apply3(to: "eggs", function: shoppingList)
// => "You need to buy 3 eggs."
apply3(to: "eggs", function: repeater)
// => "eggseggseggs"
इसी तरह, फंक्शन टाइपों को फंक्शन के रिटर्न टाइप की तरह भी इस्तेमाल किया जा सकता है। यानी ऐसे फंक्शन लिखे जा सकते हैं जो दूसरे फंक्शन बनाकर लौटाते हैं। ऐसा फंक्शन बनाते समय, जो फंक्शन लौटाया जाता है वह उस फंक्शन को दिए गए बाकी पैरामीटर या मूल फंक्शन के अंदर बनाए गए वेरिएबलो का उपयोग कर सकता है।
func makeAdder(base: Int) -> (Int) -> Int {
func adder(_ i: Int) -> Int {
base + i
}
return adder
}
// makeAdder: (Int) -> (Int) -> Int
let add10 = makeAdder(base: 10)
// add10: (Int) -> Int
let subtract20 = makeAdder(base: -20)
// subtract10: (Int) -> Int
add10(5)
// => 15
subtract20(5)
// => -15
नमस्ते, Agent Double-Null0111.
अगर आप इसे स्वीकार करना चाहें, तो आपका मिशन यह है: आपको UMBRA (United Minions Being Really Awful) के मुख्यालय में घुसना है और उनके ताज़ा, बेहद खतरनाक षड्यंत्र की योजनाएँ निकाल लानी हैं। इस मिशन को पूरा करने के लिए आपको दो टूल लिखने होंगे।
गुप्त योजनाएँ मिल जाने के बाद आपको उन्हें ऐसे सुरक्षित करना होगा कि सिर्फ वही लोग उन्हें वापस पा सकें जिन्हें पासवर्ड पता है।
इसके लिए आपको यह फंक्शन बनाना होगा: protectSecret(_ secret: String, withPassword password: String) -> (String) -> String. यह फंक्शन एक और फंक्शन लौटाता है, जो इनपुट के रूप में संभावित पासवर्ड स्ट्रिंग लेता है। अगर दिया गया पासवर्ड सही है, तो नया फंक्शन छिपा हुआ रहस्य लौटाता है। अगर पासवर्ड गलत है, तो यह फंक्शन "Sorry. No hidden secrets here." लौटाता है।
let secretFunction = protectSecret("Steal the world's supply of french fries!", withPassword: "5up3r53cr37")
secretFunction("Open sesame")
// Returns "Sorry. No hidden secrets here."
secretFunction("5up3r53cr37")
// Returns "Steal the world's supply of french fries!"
हमें पता चला है कि UMBRA अपने ठिकानों की तिजोरियों के सारे कॉम्बिनेशन उस कमरे के नंबर के आधार पर बनाती है जिसमें वह ठिकाना होता है। तिजोरी के कॉम्बिनेशन कमरे के नंबर पर बार-बार एक खास फंक्शन लगाकर बनाए जाते हैं। यानी कॉम्बिनेशन का पहला नंबर कमरे के नंबर पर फंक्शन लगाने से मिलेगा, दूसरा पहले नंबर पर फंक्शन लगाने से, और तीसरा दूसरे नंबर पर फंक्शन लगाने से।
लेकिन UMBRA कॉम्बिनेशन बनाने में इस्तेमाल होने वाला फंक्शन समय-समय पर बदलती रहती है, इसलिए कॉम्बिनेशन बनाने के लिए आपके टूल को कमरे का नंबर और उपयुक्त फंक्शन, दोनों लेने होंगे।
जो कॉम्बिनेशन आपको चाहिए होगा, उसे बनाने के लिए यह फंक्शन बनाइए: generateCombination(forRoom room: Int, usingFunction f: (Int) -> Int) -> (Int, Int, Int).
func makeCombo(_ x: Int) -> Int {
(x * 13) % 256
}
generateCombination(forRoom: 227, usingFunction: makeCombo)
// Returns (135, 219, 31)
Exercism पर साइन अप कीजिए और Swift को 35 कॉन्सेप्ट116 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।