我有一个这样的功能:
func register<T: Routable>(_ action: Action, withCallback callback: @escaping (T?) -> Void) {
notificationCenter.addObserver(forName: actionMap[action], object: nil, queue: .main, using: { notification in
let routable = T(userInfo: notification.userInfo)
callback(routable)
})
}
Run Code Online (Sandbox Code Playgroud)
其中Routable
定义如下:
protocol Routable {
init?(userInfo: [AnyHashable: Any]?)
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用它时,我收到
不能显式特化泛型函数
这是用法:
controller.register<Navigate>(Action.navigate) { [unowned self] navigate in
// do something
}
Run Code Online (Sandbox Code Playgroud)
有什么让编译器满意的想法吗?
我相信这纯粹是一个语法问题。您不能像这样直接传递类型参数。您需要“填充类型孔”。为此,您需要将类型添加到navigate
:
controller.register(Action.navigate) { [unowned self] (navigate: Navigate?) in ... }
Run Code Online (Sandbox Code Playgroud)
有时这种语法很烦人,因为它掩盖了类型。您可以通过重写register
这种方式的签名来改进它:
func register<T: Routable>(action: Action, returning: T.type,
withCallback callback: @escaping (T?) -> Void)
Run Code Online (Sandbox Code Playgroud)
然后你会这样称呼它:
controller.register(action: .navigate, returning: Navigate.self) {
[unowned self] navigate in
// ...
}
Run Code Online (Sandbox Code Playgroud)
该returning
参数不直接在函数中使用。它只是提供了一种更明确的方法来专门化函数。