【问题标题】:Optional generic type doesn't accept nil in method call可选的泛型类型在方法调用中不接受 nil
【发布时间】:2015-09-23 02:13:03
【问题描述】:

使用 Swift 2 的类型化枚举功能,我可以定义一些 事件,这些事件可以被我的应用广播和收听。这样做我可以让编译器为我检查,我也不必提供字符串。

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
}

可以广播事件,这就是执行此操作的函数。 我需要使用两种泛型类型,因为:

  • 协议“事件”只能用作通用约束,因为它具有 Self 或关联的类型要求
  • 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?)'的参数列表

这是怎么回事?

【问题讨论】:

    标签: swift


    【解决方案1】:

    类型推断并非无所不知。调用泛型方法时,编译器必须知道您正在使用的泛型类型。类型推断无法看到 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?)
    }
    

    【讨论】:

    • 完美,谢谢。我会提供不同的方法。虽然我更喜欢使用单一方法(也因为我的情况下的参数是 3:eventsendervalue,并且只需要第一个),但是对于具有重载方法的调用者来说也可以:如果你传递value,你就知道它不能是可选的,调用者不必提供casted nil
    【解决方案2】:

    这是因为通过将AnyObject 定义为泛型,您使用的是AnyObject 协议(而不是对象)。该协议不符合 NilLiteralConvertible 之一,因此它无法识别 nil 文字。

    在你的情况下,你应该这样定义你的方法:

    func broadcastEvent<E: Event>(event: E, withValue value: AnyObject? = nil)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      • 2021-08-03
      相关资源
      最近更新 更多