BangOperator BangOperator - 6 months ago 10
Swift Question

Extension on dictionary type where key and value have specific types

We need to add key value pair in dictionary of type

[String:String]
where value I am trying to add might be optional, but I need to make sure that pairs with optionals that have value are added to the dictionary and others are simply discarded.

I have tried to create an extension on dictionary for this.

extension Dictionary {
mutating func insert(stringOptinal optional : String?, forStringKey stringKey : String) {
if let stringValue = optional {
self[stringKey as! Key] = stringValue as? Value
}
}
}

var dictionary = ["1":"One","2":"Two"]

var serverFetchedStringWithString : String? = "Some String From Server,That ay or may not exists"
var serverFetchedStringWithNil : String?

//Added as key value pair
dictionary.insert(stringOptinal: serverFetchedStringWithString, forStringKey: "3")
// Not added
dictionary.insert(stringOptinal: serverFetchedStringWithNil, forStringKey: "4")

print(dictionary)

var dictionaryOfIntString = [1:"One",2:"Two"]
//An obvious crash as we are trying to insert [String:String] to a dictionary of [Int,String]
dictionaryOfIntString.insert(stringOptinal: serverFetchedStringWithString, forStringKey: "3")


This works well for all dictionaries of type
[String:String]
. But crashes when type changes (for example
[Int:String]
).

EDIT : The extension I have added is generic version, its valid for dictionaries with Hashable keys and values. How do I make sure this extension to be applicable to dictionaries of type
[String: String]
ONLY.

How do I make sure this extension is only valid for dictionaries of type
[String:String]
?

Answer

You can constrain your Dictionary extension to only work apply to keys and values that are StringLiteralConvertable by declaring it like this:

extension Dictionary where Key: StringLiteralConvertible, Value: StringLiteralConvertible {
    mutating func insert(stringOptinal optional : String?, forStringKey stringKey : String) {
        if let stringValue = optional  {
            self[stringKey as! Key] = stringValue as? Value
        }
    }
}

Your example will then generate a compiler error, but at least it won't crash.

Comments