Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can metatype (.Type) be used as Key in Dictionary?

I have something like this:

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
]

On my size dictionary definition, I get this real-time error from Xcode Editor:

Type 'AnyObject.Type' does not conform to protocol 'Hashable'

How do I accomplish what I am trying to do with size? That is, how do I create a dictionary linking types to their specific size dictionaries?

I am thinking that ObjectIdentifier would help me since it is Hashable but I do not know how to use it, or if it is the right choice.

like image 288
Jeff Avatar asked Feb 21 '16 23:02

Jeff


1 Answers

Hashable is a protocol that ObjectIdentifier implements. This means ObjectIdentifier(Lumber.Type) is hashable, not that Lumber.Type is. You could try changing your code to use ObjectIdentifier, as 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.self): lumberSize,
    ObjectIdentifier(Fruit.self): fruitSize
]

let t = size[ObjectIdentifier(Lumber.self)]
let s = t?[.small]
print(s ?? "no s?")

This compiles and prints "2x4", but I'm not sure if it meets your specific needs. Personally, I would just use the string version of the class name as the key - String(Lumber). i.e.:

let size:[String:[Size:String]] = [
    String(describing:Lumber.self): lumberSize,
    String(describing:Fruit.self): fruitSize
]

let t = size[String(describing:Lumber.self)]
let s = t?[.small]
print(s ?? "no s?")
like image 168
Michael Avatar answered Sep 24 '22 02:09

Michael