2016-08-21 37 views
1

说我有一类叫继承它LivingCreature 和其它类:制作类键入一个字典键(Equatable,可哈希)

  • Human

  • Dog

  • Alien

这就是我试图完成:

let valueForLivingCreature = Dictionary<Alien, String> 

,并获得它像这样:

let alienValue = livingCreatureForValue[Alien] 

但这意味着类应符合EquatableHashable,但是类本身,而不是类实例。 我试过完成这个的各种方法,但没有运气。

正如我想出了一个折衷办法是:

typealias IndexingValue = Int 
class LivingCreature { 
    static var indexingValue: IndexingValue = 0 
} 

,然后我可以使用类作为像这样的关键:

let livingCreatureForValue = Dictionary<IndexingValue, String> 

访问:

let alienValue = livingCreatureForValue[Alien.indexingValue] 

但是,通过这种方式,IndexingValue应该由专人设置。 我想打从类本身的哈希像这样:

class LivingCreature { 
    static var indexingValue: IndexingValue { 
     return NSStringFromClass(self).hash 
    } 
} 

这是不可能的,因为self是无法访问的是静止无功。

我的问题是,有没有更好的方法来解决这类问题?

编辑:

@ Paulw11问我为什么不把LivingCreature确认到Equatable和哈希的, 原因是我不能够由类类型引用来访问值。 我会每次都ALLOC一个实例:

let alienValue = livingCreatureForValue[Alien()] 

我不想叫“外星人()”每一次查找值。 使用它的组件不关心livingCreature实例,只关心类的类型。

+1

为什么不让'LivingCreature'符合'Equatable'和'Hashable'并覆盖相关函数? – Paulw11

+1

因为那样我就不得不每次分配LivingCreature来获得我的价值。这就是我想使用类类型的原因,而不是类实例。 – MCMatan

+0

我不明白你在说什么。如果你的类符合Hashable和Equatable,那么所有的子类都符合这些协议,你可以使用这些类的实例作为字典键。 – Paulw11

回答

5

我假设你正在尝试这样的:

let valueForLivingCreature = Dictionary<LivingCreature.Type, String> 

和:

let alienValue = valueForLivingCreature[Alien.self] 

然后你可以使用ObjectIdentifier

class LivingCreature { 
    class var classIdentifier: ObjectIdentifier { 
     return ObjectIdentifier(self) 
    } 
    //... 
} 

class Human: LivingCreature { 
    //... 
} 

class Dog: LivingCreature { 
    //... 
} 

class Alien: LivingCreature { 
    //... 
} 

let valueForLivingCreature: Dictionary<ObjectIdentifier, String> = [ 
    Human.classIdentifier: String(Human), 
    Dog.classIdentifier: String(Dog), 
    Alien.classIdentifier: String(Alien), 
] 

let alienValue = valueForLivingCreature[Alien.classIdentifier] //->"Alien" 

但在大多数使用情况下,当你想使用元类作为字典键,可以找到另一种方法:

class LivingCreature { 
    class var classValue: String { 
     return String(self) 
    } 
    //... 
} 

class Human: LivingCreature { 
    //... 
    //Override `classValue` if needed. 
} 

class Dog: LivingCreature { 
    //... 
} 

class Alien: LivingCreature { 
    //... 
} 

let alienValue = Alien.classValue //->"Alien" 
+1

ObjectIdentifier就是我在找的东西,非常感谢你 – MCMatan