Reputation: 2421
So i'm trying to extend the CollectionType protocol in Swift 2
protocol CollectionAccess: CollectionType {
func getElement<T: Hashable>(key: T) -> Self.Generator.Element?
}
extension Dictionary : CollectionAccess {
func getElement(key: Key) -> Dictionary.Element? {
if let value = self[key] {
return (key, value)
}
return nil
}
}
When it compiles it throws an error that :
error: type 'Dictionary' does not conform to protocol 'CollectionAccess' extension Dictionary : CollectionAccess
the function getElement(...) compiles fine and works fine as a n extension of Dictionary by itself BUT not as
extension Dictionary : CollectionAccess
=====progress======================
i managed to get rid of the error by changing my signature in the Dictionary extension:
extension Dictionary : CollectionAccess {
func getElement<K: Hashable where K == Dictionary.Key>(key: K) -> Dictionary.Generator.Element? {
self[key]
Now the issue is:
error: cannot subscript a value of type 'Dictionary' with an index of type 'K' self[key]
What I'm going for is setting up the signature to say the K is the same Hashable as the Dictionary.Key type is.
Upvotes: 1
Views: 793
Reputation: 13243
If it is possible to change the declaration of your protocol you can also solve this by making an associated type requirement:
protocol CollectionAccess: CollectionType {
typealias T = Hashable
func getElement(key: T) -> Self.Generator.Element?
}
Now your dictionary implementation works as expected without modification.
(But now you cannot create arrays of type [CollectionAccess]
(only as parameter in a generic function where is has to be "homogeneous"))
Upvotes: 1
Reputation: 7219
'Key' and 'Value' are placeholders in Dictionary, so you can't access these in the method signature for a CollectionType protocol extension - so to get this to work you have to do a cast.
It seems slightly wrong to me, but I think you can just about get it to work with something like this:
extension Dictionary : CollectionAccess {
func getElement<T : Hashable>(key: T) -> Dictionary.Generator.Element? {
if key.self is Key.Type {
let tKey = key as! Key
if let value = self[tKey] {
return (tKey, value)
}
}
return nil
}
}
The thing is, CollectionType doesn't have a placeholder that corresponds to Dictionary's 'Key' placeholder. Not all CollectionType's consist of key value pairs, so therefore it doesn't make sense to make CollectionType have a Key / Value type method. For example another CollectionType is Array - what would getElement return for an array?
Upvotes: 2