2016-08-21 4 views
1

Sagen, ich habe eine Klasse LivingCreature und andere Klassen genannt, die von ihm erben:Make-Klasse geben Sie eine Dictionary-Taste (gleichzusetzen, Hashable)

  • Human

  • Dog

  • Alien

Das ist, was ich versuche zu erreichen:

let valueForLivingCreature = Dictionary<Alien, String> 

Und wie so Zugang:

let alienValue = livingCreatureForValue[Alien] 

Das bedeutet aber, die Klasse zu Equatable und Hashable, aber die Klasse selbst nicht entsprechen sollte die Klasseninstanz. Ich habe verschiedene Möglichkeiten versucht, dies zu erreichen, aber kein Glück.

Als Kompromiss kam ich habe mit ist:

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

Und dann kann ich die Klasse als Schlüssel wie so verwenden:

let livingCreatureForValue = Dictionary<IndexingValue, String> 

Zugang:

let alienValue = livingCreatureForValue[Alien.indexingValue] 

Aber so sollte der IndexingValue pro Klasse von Hand gesetzt werden. Ich möchte einen Hash aus der Klasse machen sich etwa so:

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

dies nicht möglich ist, weil self nicht zugänglich ist statisch var.

Meine Frage ist, gibt es eine bessere Möglichkeit, diese Art von Problem anzugehen?

Edit:

@ Paulw11 mir die Frage, warum nicht LivingCreature zu gleichzusetzen und Hashable machen bestätigen, Der Grund ist, würde ich nicht in der Lage sein, den Wert durch die Klassentyp Referenz zuzugreifen. Ich hätte eine Instanz Alloc jedes Mal: ​​

let alienValue = livingCreatureForValue[Alien()] 

Ich will nicht nennen „Alien()“ jedes Mal einen Wert für die Suche. Und die Komponente, die es verwendet, kümmert sich nicht um die livingCreature-Instanz, nur um den Klassentyp.

+1

Warum machen Sie Ihre 'LivingCreature' nicht mit' Equatable' und 'Hashable' konform und setzen Sie die relevanten Funktionen außer Kraft? – Paulw11

+1

Denn dann müsste ich LivingCreature jedes Mal zuweisen, um meinen Wert zu erhalten. Aus diesem Grund möchte ich den Klassentyp und nicht eine Klasseninstanz verwenden. – MCMatan

+0

Ich verstehe nicht, was Sie sagen. Wenn Ihre Klasse Hashable und Equatable entspricht, entsprechen alle Unterklassen diesen Protokollen und Sie können Instanzen dieser Klassen als Dictionary-Schlüssel verwenden. – Paulw11

Antwort

5

Ich nehme an, Ihr versuchen, so etwas wie:

let valueForLivingCreature = Dictionary<LivingCreature.Type, String> 

und:

let alienValue = valueForLivingCreature[Alien.self] 

Dann können Sie ObjectIdentifier verwenden:

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" 

Aber in den meisten Anwendungsfällen, wenn Sie möchten, Verwenden Sie Meta-Klasse als einen Wörterbuchschlüssel, können Sie einen anderen Weg finden:

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 genau das, was ich gesucht habe, vielen Dank – MCMatan

Verwandte Themen