कभी-कभी डेटा ऐसा होता है जो सिर्फ कुछ तय स्थितियों में ही रह सकता है, जैसे सप्ताह के दिन, कम्पास की दिशाएँ, या कंट्रोलर के बटन। ऐसे डेटा को मॉडल करते समय Int या String जैसे बुनियादी टाइप में बड़ी कमियाँ होती हैं।
पूर्णांकों या स्ट्रिंग्स के साथ, आपके कोड को बार-बार अमान्य वैल्यू की जाँच करनी पड़ती है, जैसे 999 जैसा स्टेटस कोड या "leftt" जैसी टाइपो। साथ ही, पढ़ने वाले लोग यह आसानी से नहीं बता पाते कि संख्याएँ किस चीज़ को दर्शाती हैं।
Swift इस समस्या को एन्यूमरेशन की मदद से हल करता है (जिन्हें अक्सर एनम कहा जाता है)। एक एनम आपस में जुड़ी, नामित वैल्यू के समूह के लिए एक साझा टाइप बनाता है। चूँकि कंपाइलर सभी संभव केस पहले से जानता है, यह कंपाइल समय पर आपके कोड की सटीकता और पूर्णता जाँच सकता है। एनम में मेथड, इनिशियलाइज़र और कंप्यूटेड प्रॉपर्टी भी हो सकते हैं।
enum कीवर्ड लिखकर, उसके बाद टाइप का नाम लिखकर एनम बनाइए। इसके केस घुंघराले ब्रैकेट के अंदर लिखे जाते हैं।
Swift की परंपरा के अनुसार, टाइप के नाम में UpperCamelCase इस्तेमाल होता है, और हर केस में lowerCamelCase:
enum NESButton {
case up
case down
case left
case right
case a
case b
case select
case start
}
आप कई केस एक ही लाइन में कॉमा से अलग करके भी बना सकते हैं:
enum NESButton {
case up, down, left, right, a, b, select, start
}
किसी एनम केस को संदर्भित करने के लिए एनम टाइप का नाम, एक डॉट (.), और केस का नाम लिखिए। एक बार टाइप ज्ञात हो जाए या कंपाइलर उसे अनुमान लगा सके, तो आप टाइप का नाम छोड़ सकते हैं और छोटा डॉट सिंटैक्स इस्तेमाल कर सकते हैं:
var lastPressed = NESButton.up
// Swift infers the type, so you can omit the type name:
lastPressed = .down
let konamiCode: [NESButton] = [.up, .up, .down, .down, .left, .right, .left, .right, .b, .a]
एनम क्लास और स्ट्रक्चर की तरह मेथड और कस्टम इनिशियलाइज़र बना सकते हैं। एनम के मेथड के अंदर, self मौजूदा केस की वैल्यू को दर्शाता है:
enum Coin {
case heads
case tails
init(_ value: Int) {
if value.isMultiple(of: 2) {
self = .heads
} else {
self = .tails
}
}
func flip() -> Coin {
switch self {
case .heads: return .tails
case .tails: return .heads
}
}
}
let tails = Coin(13) // .tails
let heads = Coin(0) // .heads
let flipped = heads.flip() // .tails
एनम के केसों को रॉ वैल्यू कहलाने वाली डिफॉल्ट वैल्यू से पहले से भरा जा सकता है।
एक एनम में सभी रॉ वैल्यू का टाइप एक ही होना चाहिए (जैसे Int, String, या Character):
enum NESButton: Character {
case up = "⬆️"
case down = "⬇️"
case left = "⬅️"
case right = "➡️"
case a = "🅰️"
case b = "🅱️"
case select = "✅"
case start = "🚦"
}
print(NESButton.left.rawValue) // Prints "⬅️"
आप init(rawValue:) का उपयोग करके किसी एनम को रॉ वैल्यू से इनिशियलाइज़ कर सकते हैं। क्योंकि कोई अमान्य रॉ वैल्यू दी जा सकती है, यह इनिशियलाइज़र एक ऑप्शनल लौटाता है:
let upButton = NESButton(rawValue: "⬆️") // Optional(NESButton.up)
let invalid = NESButton(rawValue: "🙄") // nil
Swift String और Int एनम के लिए रॉ वैल्यू अपने आप असाइन कर सकता है:
String एनम में हर केस की रॉ वैल्यू उसके केस नाम पर डिफॉल्ट होती है।Int एनम में रॉ वैल्यू 0 से शुरू होती हैं और जब तक कुछ और न कहा जाए, 1-1 बढ़ती जाती हैं।enum Planet: Int {
case mercury = 1, venus, earth, mars
}
print(Planet.earth.rawValue) // Prints 3
इस अभ्यास में आप लॉग-लाइनों को संसाधित करेंगे।
हर लॉग लाइन इस प्रारूप में लिखी एक स्ट्रिंग होती है: "[<LVL>]: <MESSAGE>".
ये अलग-अलग लॉग लेवल हैं:
TRC (trace)DBG (debug)INF (info)WRN (warning)ERR (error)FTL (fatal)आपके पास तीन काम हैं, और आवश्यक कार्यक्षमता देने के लिए तीनों को पूरा करना होगा।
LogLevel नाम का एक एनम बनाइए जिसमें ऊपर दिए गए लॉग लेवलों के अनुरूप छह केस हों, साथ ही उन लेवलों के लिए एक अज्ञात केस भी हो जिनका लॉग लेवल मौजूद न हो या मानक से अलग हो।
tracedebuginfowarningerrorfatalunknownइसके बाद, LogLevel इनिशियलाइज़र बनाइए जो एक लॉग लाइन का लॉग लेवल पार्स करता हो:
LogLevel("[INF]: File deleted")
// Returns LogLevel.info
LogLevel("Something went wrong!")
// Returns LogLevel.unknown
लॉग लाइन का लॉग लेवल काफी लंबा होता है।
लॉग लाइनों को संग्रहीत करने के लिए ज़रूरी डिस्क स्थान कम करने के लिए, एक छोटा प्रारूप बनाया गया है: "<ENCODED_LEVEL>:<MESSAGE>".
एन्कोड किया गया लॉग लेवल, लॉग लेवल को एक संख्या से जोड़ने का सीधा तरीका है:
trace - 0
debug - 1
info - 4
warning - 5
error - 6
fatal - 7
unknown - 42
एक shortFormat(message: String) -> String मेथड बनाइए जो छोटा किया गया लॉग लाइन प्रारूप को एक String के रूप में दे सके:
let overflow = LogLevel.error
overflow.shortFormat(message: "Stack overflow")
// Returns "6:Stack overflow"
Exercism पर साइन अप कीजिए और Swift को 35 कॉन्सेप्ट116 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।