使用Swift 2的类型化Enum功能,我可以定义一些可由我的应用程序广播和收听的事件。这样做我可以让编译器为我检查一下,而且我也不必提供字符串。
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
}
可以广播事件,这是执行该事件的功能。 我需要使用两种泛型类型,因为:
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)
}
}
现在,此调用有效:
broadcastEvent(SettingsEvent.Baz, withValue: "aa")
虽然这些不起作用
broadcastEvent(SettingsEvent.Baz)
broadcastEvent(SettingsEvent.Baz, withValue: nil)
编译器说:
错误:无法使用类型为'(SettingsEvent,withValue:NilLiteralConvertible)'的参数列表调用'broadcastEvent'
注意:期望一个类型'(E,withValue:V?)'
的参数列表
这有什么问题?
答案 0 :(得分:4)
类型推断不是无所不知的。在调用泛型方法时,编译器必须知道您正在使用的泛型类型。类型推断无法看到nil
应该是什么类型,因此您必须明确指定类型。
broadcastEvent(SettingsEvent.Baz, withValue: nil as NSString?)
另请注意,String
是struct
,因此它不符合AnyObject
。使用文字"aa"
会使其成为NSString
。
我认为您只能通过定义单独的方法将通用类型与默认参数值nil
组合在一起
func broadcastEvent<E: Event>(event: E) {
broadcastEvent(event, withValue: nil as AnyObject?)
}
答案 1 :(得分:0)
这是因为通过将AnyObject
定义为通用,您使用的是AnyObject
协议(而不是对象)。该协议不符合NilLiteralConvertible
协议,因此无法识别 nil 文字。
在你的情况下,你应该像这样定义你的方法:
func broadcastEvent<E: Event>(event: E, withValue value: AnyObject? = nil)