Using the typed Enum feature of Swift 2 I can define some events that can be broadcasted and listened by my app. Doing so I can have the compiler check things for me and also I don't have to provide strings.
protocol Event: RawRepresentable {}
// Somewhere in a view
enum SettingsEvent: String, Event {
case Bar
case Baz
}
// Somewhere else in the app
enum ViewEvents: String, Event {
case Foo
case Bar
}
Events can be broadcasted, and this is the function that performs that. I need to use two generic types because:
func broadcastEvent<E: Event, V: AnyObject>(event: E, withValue value: V? = nil) {
// Do something with event and value. This is not the real function body
print(event.rawValue)
if let v = value {
print(v)
}
}
Now, this call works:
broadcastEvent(SettingsEvent.Baz, withValue: "aa")
While these don't work
broadcastEvent(SettingsEvent.Baz)
broadcastEvent(SettingsEvent.Baz, withValue: nil)
The compiler says:
error: cannot invoke 'broadcastEvent' with an argument list of type '(SettingsEvent, withValue: NilLiteralConvertible)'
note: expected an argument list of type '(E, withValue: V?)'
What's wrong with this?
Type inferring is not omniscient. When invoking a generic method, the compiler has to know the generic types you are using. Type inferring cannot see what type is nil
supposed to be so you have to specify the types explicitly.
broadcastEvent(SettingsEvent.Baz, withValue: nil as NSString?)
Also note that String
is a struct
so it doesn't conform to AnyObject
. Using a literal "aa"
will make it a NSString
.
I don't think you will be able to combine a generic type with a default parameter value of nil
, only by defining a separate method
func broadcastEvent<E: Event>(event: E) {
broadcastEvent(event, withValue: nil as AnyObject?)
}
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