2016-02-21 12 views
5

Ich habe so etwas wie dies:Kann Metatyp (.Type) als Schlüssel im Wörterbuch verwendet werden?

class Lumber { } 
class Fruit { } 

enum Size { 
    case Small 
    case Medium 
    case Large 
} 

let lumberSize = [ 
    Size.Small: "2x4", 
    Size.Medium: "4x6", 
    Size.Large: "6x10" 
] 

let fruitSize = [ 
    Size.Small: "grape", 
    Size.Medium: "apple", 
    Size.Large: "watermelon" 
] 

let size:[AnyObject.Type:Dictionary] = [ 
    Lumber.Type: lumberSize, 
    Fruit.Type: fruitSize 
] 

Auf meiner size Wörterbuch-Definition, erhalte ich diese Echtzeit-Fehler von Xcode Editor:

Typ 'AnyObject.Type' entspricht nicht Protokoll ' Hashable '

Sie könnten denken, dies würde die Dinge regeln. Wenn ich X als Schlüssel in einem Wörterbuch verwenden möchte und es nicht hashbar ist, kann es einfach nicht verwendet werden. Das macht Sinn.

Zwei Dinge lassen mich jedoch die Fehlermeldung bezweifeln.

Zunächst sind zu diesem Zeitpunkt die Echtzeit-Xcode-Editor-Fehlermeldungen schrecklich über die Grundlagen hinaus. Mehrmals am Tag muss ich seine Vermutungen über das, was falsch ist, ignorieren und an der Syntax herumfummeln, bis sie akzeptiert wird.

Zweitens denke ich, lesen Wörter in der Dokumentation, die die Fehlermeldung widerlegen. Im Swift 2.2 Language Reference unter Typen, heißt es:

Die Metatyp einer Klasse, Struktur oder Aufzählungstyp ist der Name dieser Art gefolgt von .Type

Und im Swift Standard Library ReferenceObjectstruktur Referenz lautet:

In Swift, nur Klasseninstanzen und Metatypen eindeutige Identitäten haben.

Und dieser Abschnitt listet auch Hashable als ein Protokoll, das es entspricht.

Wenn ich das richtig lese, dann haben alle Typen eineObjectIdentifier, die von Hashable verwendet wird. Ich habe (falsch?) Vergleichbares als Beispiel verwendet. Wir können Typen vergleichen, weil ihr ObjectIdentifier mit Comparable übereinstimmt? Da ObjectIdentifier auch mit Hashable übereinstimmt, sollte ich in der Lage sein, es in einem Wörterbuch zu verwenden.

So im Moment bin ich misstrauisch, dass was ich beabsichtige zu tun ist eigentlich möglich, aber dass ich einfach nicht die Syntax richtig bekommen kann.

Antwort

7

Hashable ist ein Protokoll, das ObjectIdentifier implementiert. Das bedeutet ObjectIdentifier(Lumber.Type) ist waschbar, nicht dass Lumber.Type ist. Sie könnten versuchen, Ihren Code zu ändern Object zu verwenden, wie in:

class Lumber { } 
class Fruit { } 

enum Size { 
    case Small 
    case Medium 
    case Large 
} 

let lumberSize = [ 
    Size.Small: "2x4", 
    Size.Medium: "4x6", 
    Size.Large: "6x10" 
] 

let fruitSize = [ 
    Size.Small: "grape", 
    Size.Medium: "apple", 
    Size.Large: "watermelon" 
] 

let size:[ObjectIdentifier: [Size: String]] = [ 
    ObjectIdentifier(Lumber): lumberSize, 
    ObjectIdentifier(Fruit): fruitSize 
] 

Dies kompiliert, aber ich bin nicht sicher, ob es für Ihre speziellen Bedürfnisse. Persönlich würde ich nur die String-Version des Klassennamens als Schlüssel verwenden - String(Lumber). d. h .:

let size:[String: [Size: String]] = [ 
    String(Lumber): lumberSize, 
    String(Fruit): fruitSize 
] 
+0

Ich hatte gehofft, die String-Konvertierung zu vermeiden, wenn nur für ein tieferes Verständnis von Swift. +1 für den Bildungsaspekt. Wenn ich am nächsten Wochenende nicht herausfinde, was ich vorhabe, werde ich diese (oder eine andere) Antwort akzeptieren. Vielen Dank. – Jeff

Verwandte Themen