可选的泛型类型在方法调用中不接受nil

时间:2015-09-22 16:55:13

标签: swift

使用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
}

可以广播事件,这是执行该事件的功能。 我需要使用两种泛型类型,因为:

  • 协议'事件'只能用作通用约束,因为它具有自我或相关类型要求
  • V传递给我控制的另一个通用集合
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?)'

的参数列表

这有什么问题?

2 个答案:

答案 0 :(得分:4)

类型推断不是无所不知的。在调用泛型方法时,编译器必须知道您正在使用的泛型类型。类型推断无法看到nil应该是什么类型,因此您必须明确指定类型。

broadcastEvent(SettingsEvent.Baz, withValue: nil as NSString?)

另请注意,Stringstruct,因此它不符合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)