Is there a way to make the following actually work?
protocol testProtocol { // } class test { var s : Set<testProtocol>? init(){ } }
protocol testProtocol : Hashable { // } class test { var s : Set<testProtocol>? init(){ } }
I'm assuming that the answer is no - because protocols (even with the @objc tag) do not have enough information?? but maybe there is some sort of line or thing i'm missing here.
You can not create an instance of protocol. But however you can refer an object in your code using Protocol as the sole type.
You can use any type that conforms to the Hashable protocol in a set or as a dictionary key. Many types in the standard library conform to Hashable : Strings, integers, floating-point and Boolean values, and even sets are hashable by default.
A protocol can have properties as well as methods that a class, enum or struct conforming to this protocol can implement. A protocol declaration only specifies the required property name and type.
One protocol can inherit from another in a process known as protocol inheritance. Unlike with classes, you can inherit from multiple protocols at the same time before you add your own customizations on top. Now we can make new types conform to that single protocol rather than each of the three individual ones.
One solution is to wrap the set in a class or structure, and constrain the insertion function so that it only accepts items that conform to your protocol and to hashable. You can then use a Set
of AnyHashable
in the implementation.
For example:
protocol MyProtocol { func doStuff() } class MyProtocolSet { var set = Set<AnyHashable>() func insert<T>(_ item: T) where T: MyProtocol, T: Hashable { set.insert(AnyHashable(item)) } func iterate( doing: (MyProtocol) -> Void ) { for item in set { doing(item as! MyProtocol) } } } struct Foo: MyProtocol, Hashable { func doStuff() { print("foo") } } struct Bar: MyProtocol, Hashable { func doStuff() { print("bar") } } func test() { let set = MyProtocolSet() set.insert(Foo()) set.insert(Bar()) set.iterate { (item: MyProtocol) in item.doStuff() } }
By putting the constraints on the insertion function, you're saying "this set has to contain things that conform to the protocol, and are hashable", without actually constraining the protocol to being hashable.
It would be even nicer if the wrapping set class could itself be generic, and take in the protocol to conform to, but I haven't figured out if that is possible yet!
Perhaps there is a better solution, but you can make your class generic:
protocol testProtocol : Hashable { // } class test<P: testProtocol> { var s : Set<P>? init() { } }
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