1

I have a dictionary, [String: ComponentObject]() in Swift 2 and I have been unable to write an extension for this type. However, when I make ComponentObject a class instead of a protocol, then it works as expected.

Here is a playground that demonstrates the basic setup for the dictionary:

import Foundation

protocol ComponentObject {
    var name: String { get }
}

private var _idPrev = 0;
private func defaultName(baseName: String) -> String {
    return baseName + String(++_idPrev)
}

class Thing : ComponentObject {
    let name: String

    init(name: String? = nil) {
        self.name = name ?? defaultName("thing")
    }
}

class OtherThing : ComponentObject {
    let name: String

    init(name: String? = nil) {
        self.name = name ?? defaultName("other")
    }
}

let w = Thing()
w.name

let m = OtherThing()
m.name

var d = [String: ComponentObject]()
d[w.name] = w
d[m.name] = m

let c = d["other2"]!

c.name

When I write the extension like this:

public extension Dictionary where
    Key: StringLiteralConvertible, Value: ComponentObject {
    public func getByPath(path: Key) -> Value? {
        // TODO: Some other stuff...
        return self[path]
    }
}

I get an error when I call getByPath:

let c2 = d.getByPath("other2")!
// Error: Using ComponentObject as a concrete type conforming to protocol
// 'ComponentObject' is not supported.

Apple states that "Because it is a type, you can use a protocol in many places where other types are allowed" here and shows examples of using protocols as the value in a collection here. So, what am I doing wrong?

Wayne Bloss
  • 5,370
  • 7
  • 50
  • 81
  • I found [the answer](https://swiftlang.ng.bluemix.net/#/repl/496048b1d646de018d05d80c700fa9b4c02620b39be9588010cd4b4c4abad01d) elsewhere and I will update this question with it if nobody else wants to do so. According to the source (on IRC), "you can use protocols to hack around the inability to write `where Value == ComponentObject`..." – Wayne Bloss Mar 10 '16 at 20:22
  • Alternative solution from the same source on IRC, "you can either add all the Dictionary methods you need to use to the protocol, like I did with subscript, or you can just cast `self` to `Dictionary` inside your code" to which they added "all kinda ugly" :) I know. I'm learning! – Wayne Bloss Mar 10 '16 at 20:27

0 Answers0