I want to create an extension on Dictionary that only affects dictionaries with type [String:AnyObject], which is the data type returned from parsed JSON dictionaries. Here's how I set it up:
typealias JSONDictionary = [String : AnyObject]
extension Dictionary where Element:JSONDictionary {
// Some extra methods that are only valid for this type of dictionary.
}
Xcode is generating an error on Element
, saying it's an undeclared type. However, the first line of the definition of Dictionary is a typealias declaring Element. What am I doing wrong here?
Element
is a tuple:
typealias Element = (Key, Value)
That cannot match the type you're trying to compare it to (a Dictionary). You can't even say something like where Element:(String, AnyObject)
because tuples don't subtype that way. For example, consider:
var x: (CustomStringConvertible, CustomStringConvertible) = (1,1)
var y: (Int, Int) = (1,1)
x = y // Cannot express tuple conversion '(Int, Int)' to ('CustomStringConvertible', 'CustomStringConvertible')
Compare:
var x1:CustomStringConvertible = 1
var y1:Int = 1
x1 = y1 // No problem
I suspect you get "undeclared type" is because Element
is no longer an unbound type parameter, it's a bound type parameter. Dictionary
is conforming to SequenceType
here. So you can't parameterize on it (at least not in one step; you have to chase it through another layer of type parameters to discover it's "ultimately" unbound). That seems a bad error message, but I suspect it bubbles out of "undeclared type out of the list of types that could possibly be used here." I think that's worth opening a radar on for a better error message.
Instead, I think you mean this:
extension Dictionary where Key: String, Value: AnyObject { }
EDIT for Swift 2:
This is no longer legal Swift. You can only constrain based on protocols. The equivalent code would be:
protocol JSONKey {
func toString() -> String
}
extension String: JSONKey {
func toString() -> String { return self }
}
extension Dictionary where Key: JSONKey, Value: AnyObject { ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With