dictionary - tag - took ka matlab
मैं स्विफ्ट एन्यूम को एक शब्दकोश कुंजी के रूप में कैसे उपयोग कर सकता हूं?(समानता के अनुरूप) (3)
मैंने "स्टेशन" के चयन का प्रतिनिधित्व करने के लिए एक मान परिभाषित किया है; स्टेशनों को एक विशिष्ट सकारात्मक पूर्णांक द्वारा परिभाषित किया जाता है, इसलिए मैंने निम्न मान को विशेष चयनों का प्रतिनिधित्व करने के लिए नकारात्मक मूल्यों को अनुमति देने के लिए बनाया है:
enum StationSelector : Printable {
case Nearest
case LastShown
case List
case Specific(Int)
func toInt() -> Int {
switch self {
case .Nearest:
return -1
case .LastShown:
return -2
case .List:
return -3
case .Specific(let stationNum):
return stationNum
}
}
static func fromInt(value:Int) -> StationSelector? {
if value > 0 {
return StationSelector.Specific(value)
}
switch value {
case -1:
return StationSelector.Nearest
case -2:
return StationSelector.LastShown
case -3:
return StationSelector.List
default:
return nil
}
}
var description: String {
get {
switch self {
case .Nearest:
return "Nearest Station"
case .LastShown:
return "Last Displayed Station"
case .List:
return "Station List"
case .Specific(let stationNumber):
return "Station #\(stationNumber)"
}
}
}
}
मैं इन मानों को एक शब्दकोश में कुंजी के रूप में उपयोग करना चाहता हूं एक डिक्शनरी की घोषणा करने से अपेक्षित त्रुटि उत्पन्न होती है कि स्टेशनशिपक हाशनीय के अनुरूप नहीं होता है। हाशनीय के अनुरूप होना एक सरल हैश फ़ंक्शन के साथ आसान है:
var hashValue: Int {
get {
return self.toInt()
}
}
हालांकि, Equatable
को Equatable
करने के लिए अनुरूप होना Equatable
, और मैं कंपाइलर को संतुष्ट करने के लिए अपने Equatable
के बराबर ऑपरेटर को परिभाषित नहीं कर सकता।
func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.toInt() == rhs.toInt()
}
कंपाइलर शिकायत करता है कि यह एक पंक्ति पर दो घोषणाएं हैं और एक रखना चाहता है ;
func
बाद, जो समझ में नहीं आता है, या तो
कोई विचार?
मुझे कुछ हद तक प्रयास करने के लिए संघर्ष करने की कोशिश की, जो कि संबद्ध मूल्यों के साथ एक enum
बनाने की कोशिश करता है।
यहां मैंने अपने मान को संबद्ध मानों के साथ Hashable
अनुरूप बना दिया Hashable
ताकि इसे सॉर्ट किया जा सकता है या Dictionary
कुंजी के रूप में इस्तेमाल किया जा सकता है, या जो कुछ भी Hashable
कर सकता है
आपको अपने संबंधित मूल्यों को Hashable
बनाने के लिए करना चाहिए, क्योंकि संबद्ध मूल्यों में एक कच्चे प्रकार नहीं हो सकते हैं।
public enum Components: Hashable {
case None
case Year(Int?)
case Month(Int?)
case Week(Int?)
case Day(Int?)
case Hour(Int?)
case Minute(Int?)
case Second(Int?)
///The hashValue of the `Component` so we can conform to `Hashable` and be sorted.
public var hashValue : Int {
return self.toInt()
}
/// Return an 'Int' value for each `Component` type so `Component` can conform to `Hashable`
private func toInt() -> Int {
switch self {
case .None:
return -1
case .Year:
return 0
case .Month:
return 1
case .Week:
return 2
case .Day:
return 3
case .Hour:
return 4
case .Minute:
return 5
case .Second:
return 6
}
}
}
इसके अलावा समानता ऑपरेटर को ओवरराइड करना भी आवश्यक है:
/// Override equality operator so Components Enum conforms to Hashable
public func == (lhs: Components, rhs: Components) -> Bool {
return lhs.toInt() == rhs.toInt()
}
शब्दकोश कुंजी के रूप में एन्यूमरेशन पर जानकारी:
स्विफ्ट बुक से:
गणना मूल्यों के बिना मूल्यों के मूल्यों को मान (जैसा कि एन्यूमरेशन में वर्णित है) भी डिफ़ॉल्ट रूप से भी हैं।
हालांकि, आपकी गणना में संबद्ध मूल्य के साथ एक सदस्य का मान होता है, इसलिए आपके द्वारा मैन्युअल रूप से Hashable
अनुरूपता Hashable
होगी
उपाय
आपके कार्यान्वयन के साथ समस्या, यह है कि स्विफ्ट में ऑपरेटर घोषणा वैश्विक स्तर पर होनी चाहिए।
बस चलें:
func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.toInt() == rhs.toInt()
}
enum
परिभाषा के बाहर और यह काम करेगा।
उस पर और अधिक के लिए दस्तावेज़ों की जांच करें।
अधिक पठनीयता के लिए, चलो स्विफ्ट 3 के साथ StationSelector
को पुन:
enum StationSelector {
case nearest, lastShown, list, specific(Int)
}
extension StationSelector: RawRepresentable {
typealias RawValue = Int
init?(rawValue: RawValue) {
switch rawValue {
case -1: self = .nearest
case -2: self = .lastShown
case -3: self = .list
case (let value) where value >= 0: self = .specific(value)
default: return nil
}
}
var rawValue: RawValue {
switch self {
case .nearest: return -1
case .lastShown: return -2
case .list: return -3
case .specific(let value) where value >= 0: return value
default: fatalError("StationSelector is not valid")
}
}
}
एप्पल डेवलपर एपीआई संदर्भ Hashable
प्रोटोकॉल के बारे में बताता है:
जब आप किसी मूल्य के बिना एक गणन को परिभाषित करते हैं, तो यह अपने आप में
Hashable
अनुरूपता प्राप्त कर लेता है, और आप एक भीhashValue
संपत्ति जोड़कर अपने अन्य कस्टम प्रकारों के लिएhashValue
अनुरूपता जोड़ सकते हैं।
इसलिए, क्योंकि StationSelector
संबद्ध मान लागू करता है, आपको Hashable
मैन्युअल रूप से Hashable
प्रोटोकॉल के अनुरूप बनाना चाहिए।
पहला कदम ==
ऑपरेटर को कार्यान्वित करना है और Equatable
प्रोटोकॉल के अनुरूप है:
extension StationSelector: Equatable {
static func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.rawValue == rhs.rawValue
}
}
उपयोग:
let nearest = StationSelector.nearest
let lastShown = StationSelector.lastShown
let specific0 = StationSelector.specific(0)
// Requires == operator
print(nearest == lastShown) // prints false
print(nearest == specific0) // prints false
// Requires Equatable protocol conformance
let array = [nearest, lastShown, specific0]
print(array.contains(nearest)) // prints true
एक बार Equatable
प्रोटोकॉल लागू किया जाता है, तो आप Equatable
प्रोटोकॉल के अनुरूप बना सकते हैं:
extension StationSelector: Hashable {
var hashValue: Int {
return self.rawValue.hashValue
}
}
उपयोग:
// Requires Hashable protocol conformance
let dictionnary = [StationSelector.nearest: 5, StationSelector.lastShown: 10]
निम्नलिखित कोड, StationSelector
लिए आवश्यक कार्यान्वयन को दिखाता है ताकि इसे स्विफ्ट 3 का प्रयोग करके Hashable
प्रोटोकॉल के अनुरूप बनाया जा सके:
enum StationSelector: RawRepresentable, Hashable {
case nearest, lastShown, list, specific(Int)
typealias RawValue = Int
init?(rawValue: RawValue) {
switch rawValue {
case -1: self = .nearest
case -2: self = .lastShown
case -3: self = .list
case (let value) where value >= 0: self = .specific(value)
default: return nil
}
}
var rawValue: RawValue {
switch self {
case .nearest: return -1
case .lastShown: return -2
case .list: return -3
case .specific(let value) where value >= 0: return value
default: fatalError("StationSelector is not valid")
}
}
static func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.rawValue == rhs.rawValue
}
var hashValue: Int {
return self.rawValue.hashValue
}
}