【问题标题】:Partial function application with generics具有泛型的部分函数应用程序
【发布时间】:2015-02-05 20:36:26
【问题描述】:

我正在使用具有以下功能的Observer API (ObserverSet):

public func add<T: AnyObject>(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry<Parameters>

它只是注册一个object,然后在通知触发时在object上调用实例方法f

在我的一位经理中,我需要用我的一位经理隐藏前一个函数,以便我可以强制观察者调用通过协议实现的预定义函数。

这是我到目前为止所做的:

@objc protocol Observer : NSObjectProtocol {
    func observe(param: String) -> Void
}

func addObserver<T: AnyObject where T: Observer>(observer: T) {
    let f: T -> String -> Void = observer.dynamicType.observe
    entries.addObserver(observer, f)
}

不幸的是,我出现了以下错误Partial application of generic method is not allowed

我在 SO 的某个地方找到了一种可能的解决方法,看起来像这样:

let f: T -> String -> Void = { (obs: T) in obs.dynamicType.observe(obs) }

但是这行代码让我的 XCode 在编译时用一些 Segmentation Fault: 11 发疯了(以及 Communication interruptedPlayground ..)

对于我正在尝试做的事情有什么解决方法吗?

【问题讨论】:

  • 如果您将协议声明为纯 Swift 协议而不是将其降级为 objc 协议会怎样?
  • 完全相同的错误。如果我还删除了NSObjectProtocol 的实现,我会得到error: 'T' is not a subtype of 'inout T'

标签: ios swift generics currying partial-application


【解决方案1】:

我没有测试,但你可以试试:

@objc protocol Observer : NSObjectProtocol {
    func observe(param: String) -> Void
}

func addObserver<T: AnyObject where T: Observer>(observer: T) {
    let f: T -> String -> Void = { ($0 as AnyObject).observe }
    entries.addObserver(observer, f)
}

至少,这是可以编译的,因为 AnyObject 具有来自 ObjC 的所有方法 - 包括 @objc - 类/协议,如 ImplicitlyUnwrappedOptional

所以,这编译:

let str = NSString(string: "test")
(str as AnyObject).observe("foo")

这当然会导致运行时错误,因为NSString 没有observe(_:) 方法。但是,在你的情况下,T 保证是Observer,它应该可以工作。

【讨论】:

  • 耶!那个演员做到了。但我不明白为什么没有它我会有分段错误? &lt;T: AnyObject where T: Observer&gt; 已经告诉 TAnyObject 对吧?可能的错误?
  • Segfault 冲突本身绝对是一个错误。但我不确定强制转换的要求,这可能是语言限制。如果是这样,编译器应该报告相应的错误信息。
猜你喜欢
  • 2021-09-04
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
相关资源
最近更新 更多