How to create Dictionary that can hold anything in Key? or all the possible type it capable to hold

前端 未结 8 2051
感动是毒
感动是毒 2020-12-05 04:13

I want to create a Dictionary that does not limit the key type (like NSDictionary)

So I tried

var dict = Dictionary

        
相关标签:
8条回答
  • 2020-12-05 04:31

    This doesn't exactly answer the question, but has helped me.

    The general answer would be implement Hashable for all your types, however that can be hard for Protocols because Hashable extends Equatable and Equatable uses Self which imposes severe limitations on what a protocol can be used for.

    Instead implement Printable and then do:

    var dict = [String: Int]
    dict[key.description] = 3
    

    The implementation of description has to be something like:

    var description : String {
        return "<TypeName>[\(<Field1>), \(<Field2>), ...]"
    }
    

    Not a perfect answer, but the best I have so far :(

    0 讨论(0)
  • 2020-12-05 04:32

    This does not answer the OP's question, but is somewhat related, and may hopefully be of use for some situations. Suppose that what you really want to do is this:

       public var classTypeToClassNumber = [Any.Type : Int]()
    

    But Swift is telling you "Type 'Any.Type' does not conform to protocol Hashable".

    Most of the above answers are about using object instances as a dictionary key, not using the type of the object. (Which is fair enough, that's what the OP was asking about.) It was the answer by Howard Lovatt that led me to a usable solution.

    public class ClassNumberVsClassType {
    
       public var classTypeToClassNumber = [String : Int]()
    
       public init() {
    
          classTypeToClassNumber[String(describing: ClassWithStringKey.self)] = 367622
          classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList3.self)] = 367629
          classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList2.self)] = 367626
          classTypeToClassNumber[String(describing: ClassWithGuidKey.self)] = 367623
          classTypeToClassNumber[String(describing: SimpleStruct.self)] = 367619
          classTypeToClassNumber[String(describing: TestData.self)] = 367627
          classTypeToClassNumber[String(describing: ETestEnum.self)] = 367617
          classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList0.self)] = 367624
          classTypeToClassNumber[String(describing: ClassBasedOnKeyedItemList1.self)] = 367625
          classTypeToClassNumber[String(describing: SimpleClass.self)] = 367620
          classTypeToClassNumber[String(describing: DerivedClass.self)] = 367621
       }
    
       public func findClassNumber(_ theType : Any.Type) -> Int {
          var s = String(describing: theType)
          if s.hasSuffix(".Type") {
             s = s.substring(to: s.index(s.endIndex, offsetBy: -5))  // Remove ".Type"
          }
          let classNumber = _classTypeToClassNumber[s]
          return classNumber != nil ? classNumber! : -1
       }
    }
    

    EDIT:

    If the classes involved are defined in different modules, and may have conflicting class names if you neglect the module name, then substitute "String(reflecting:" for "String(describing:", both when building up the dictionary and when doing the lookup.

    0 讨论(0)
提交回复
热议问题