0
votes

I would like to define a dictionary that allows multiple specific types for values. I can currently define a dictionary like this:

var foo = [String: String]

which constrains the value to one specific type

OR

var foo = [String: AnyObject]

which constrains the value to AnyObject, which is not particularly constrained.

I'd like to do something like:

var foo = [String: <String, Int>]

which would allow me to insert only strings or ints as values in this dictionary.

I've considered the use of an enum as seen here: Generic dictionary value type in Swift but I would rather find a way that allows me to dynamically specify the types without expanding or creating a new enum.

var bar = [String: <String, Int, Bool, MyClass>]

It seems that I should be able to create a wrapper class with an internal dictionary of [String: AnyObject] that will allow for compile time type checking against an arbitrarily long list of classes that can be inserted.

class ECDictionary<T> {

    private var internal_storage = [String: AnyObject]()

    subscript(s: String) -> T {
        get {
            return internal_storage[s]
        }
        set(newValue) {
            internal_storage[s] = newValue
        }
    }
}


var myECDictionary = ECDictionary<String, Int, OtherClass>()

I could build this with runtime type checking, but I'd rather it be enforced at compile time. Is this possible in any way?

1

1 Answers

5
votes

If you want to a Dictionary where the value can be a String, an Int, a Bool or a MyClass you should

Define your protocol

protocol MyDictionaryValue { }

Conform String, Int, Bool and MyClass to MyDictionaryValue

extension String: MyDictionaryValue { }
extension Int: MyDictionaryValue { }
extension Bool: MyDictionaryValue { }
extension MyClass: MyDictionaryValue { }

Declare your dictionary

var dict = [String:MyDictionaryValue]()

Usage

dict["a"] = "a string"
dict["b"] = 1
dict["c"] = true
dict["d"] = MyClass()

dict["e"] = CGPointZero // error
dict["f"] = UIView() // error