Post

Replies

Boosts

Views

Activity

Best workaround for the lack of generic protocols
Let's say I have a protocol "ValueProvider", which is just something that provides a value:protocol ValueProvider { typealias ValueType func valueInContext(context: ValueProviderContext) -> ValueType }I have various structs that implement this protocol, such as:struct Constant<T>: ValueProvider { var value: T init(value: T) { self.value = value } func value(context: ValueProviderContext) -> T { return value } }and many other such (generic) structs.I have another struct, Thing, that has properties which are value provides of particular type. Ideally, I would like to express it like this:struct Thing { var position: ValueProvider<CGPoint> var name: ValueProvider<String> ... }Unfortunately I cannot do this, because ValueProvider is a protocol (which cannot be generic in current version of Swift), and ValueProvider<String> is illegal as a property type.It looks to me I basically have two options:(1) Make a new generic ThingProperty<T> enum, use that as the type of the "position" and "name" properties. The enum will have a value provider as its associated value. I don't like this solution because it forces me to change my model only because the type system cannot express what I want, although the runtime shouldn't have any problem with what I want. It feels like changing my model just to make the typechecker happy, which is absurd.(2) Instead of "ValueProvider<CGPoint>", I can just use "ValueProvider" as the type of the position (and name) properties. This works and allows me to keep the model simple, but I loose the benefits of static typing to a large degree - the system doesn't know that the "position" and "model" properties can only hold CGPoint and String value providers, respectively. As a consequence, when I call valueInContext method on those properties, type checker wouldn't know the correct type of the return value.What's the "correct" approach to take here? Am I missing something?
25
0
20k
Jun ’15