Reputation: 31
I've run into a conceptual problem and am looking for advice. I have a base class that defines all of the common properties a given object type:
class Widget {
var id: Int
var type: String
}
Many of these widgets share other properties and capabilities that are easily grouped. The properties / capabilities fit nicely into protocols:
protocol WidgetryA {
func widgetAFunc()
}
protocol WidgetryB {
func widgetBFunc()
}
It's easy to extend the Widget class to conform to these various protocols:
extension Widget: WidgetryA {
func widgetAFunc() { }
}
Note that Widgets may conform to multiple protocols. No problem so far! What I would like to do, and what I'm struggling with, is the following... Widgets that have a certain Widget.type value should essentially be disallowed from conforming to a given Widgetry protocol. So for example:
// this obviously doesn't work with where -- is there an alternative?
extension Widget: WidgetryA where Self.type == "foo" {
func widgetAFunc() { }
}
Now I could do something gross and inelegant like guard()ing in protocol functions to prevent Widgets of the wrong Widget.type from making calls that they shouldn't. I feel like associated types might provide a workable path to achieving what I want, but I am struggling coming up with a construct which works. Any thoughts or advice would be appreciated!
Upvotes: 3
Views: 1590
Reputation: 1054
Restrict protocols to be adopted by a specific class like this :
My Protocol: MyViewController {
func myMethod()
}
Upvotes: 0
Reputation: 575
You can do an extension of the protocol:
extension WidgetryA where Self: Foo {
func widgetAFunc() { }
}
so this widgetAFunc
will be implemented only for classes that are of Foo
type and conform to WidgetryA
protocol. And of course you'd have to create subclasses of Widget
.
Upvotes: 1
Reputation: 13679
This isn't possible as described in Swift for a couple reasons:
The Swift compiler doesn't know what the runtime values for the "type" property will be
Swift's generics and protocol extensions don't support excluding / disallowing / removing methods and implementations based on constraints, nor do generic constraints support matching types that are NOT something.
However, rather than using the type string, I would suggest making the Widget "type" a protocol itself, and then add the implementations via protocol extension to only instances that are Widgets that conform to the correct type protocol(s)
Upvotes: 0