Swift 使用闭包时无法显式专门化泛型函数

Swift 使用闭包时无法显式专门化泛型函数,swift,generics,Swift,Generics,我有这样一个函数: 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(u

我有这样一个函数:

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)
    })
}
当我尝试使用它时,我收到

无法显式专门化泛型函数

这是用法:

controller.register<Navigate>(Action.navigate) { [unowned self] navigate in
    // do something
}
controller.register(Action.navigate){[unowned self]导航到
//做点什么
}

想让编译器高兴吗?

如果没有更完整的代码示例,很难说。。。但基本上,编译器告诉你的是“你告诉我你希望寄存器函数是泛型的(因为它有一个类型参数),但是你也试图告诉我要使用什么类型,我不喜欢这样”

当您在调用中添加特定类型参数时,您将“显式专门化”函数:

controller.register<Navigate>...
# Right Here       ^^^^^^^^^^

不显式专门化泛型函数,但让编译器确定使用哪种专门化。

我认为这纯粹是语法问题。不能像这样直接传递类型参数。您需要“填充类型孔”。为此,您需要将类型添加到
导航

controller.register(Action.navigate) { [unowned self] (navigate: Navigate?) in ... }
有时,这种语法很烦人,因为它隐藏了类型。您可以通过以下方式重写
寄存器的签名来改进它:

func register<T: Routable>(action: Action, returning: T.type,
                           withCallback callback: @escaping (T?) -> Void)
controller.register(action: .navigate, returning: Navigate.self) { 
    [unowned self] navigate in 
    // ...
}

函数中不直接使用返回的
参数。它只是提供了一种更明确的方法来专门化函数。

Rob,谢谢!A最后,当我在考虑一个解决方案时,我得到了第二个解决方案。
func register<T: Routable>(action: Action, returning: T.type,
                           withCallback callback: @escaping (T?) -> Void)
controller.register(action: .navigate, returning: Navigate.self) { 
    [unowned self] navigate in 
    // ...
}