【问题标题】:Declare a function in Swift that returns a closure with a generic T.Type在 Swift 中声明一个函数,该函数返回一个带有泛型 T.Type 的闭包
【发布时间】:2017-04-21 11:13:44
【问题描述】:

我们正在尝试在 Swift 中创建一个返回闭包的函数。返回类型如下:

func completionBlock() -> (Response<T, NSError>) -> ()

其中 Response 本身是一个具有 2 个泛型的结构。第二个总是 NSError,但第一个取决于一个开关。

回应声明:

public struct Response<Value, Error: ErrorType> { ...

我们想要实现的是一个函数,它将返回一个类型取决于变量值的闭包。 根据这个值,加上一个开关,它指定了一种或另一种类型,对泛型参数的唯一要求是它必须符合特定的协议,但我们找不到解决方案。

到目前为止,我们得到的是:

class BaseClass {
    var endpoint: Int
    ... 

    func completionBlock() -> (Response<T, NSError>) -> () {

        switch endpoint
        {
        case 1:
            return getHandleResponseClosure(Car.self)
        case 2:
            return getHandleResponseClosure(Truck.self)
        }
    }

    func getHandleResponseClosure<T: Mappable>(_: T.Type) -> (Response<T, NSError>) -> () {

        let closure = { (_: Response<T, NSError>) -> () in
            // ...
        }
        return closure
    }

}

但这不编译:"Use of undeclared Type T" at func completionBlock(),此时的类型是泛型的,只需要符合到协议 Mappable,但我们不知道如何指定它。

谢谢!!,问候

【问题讨论】:

  • 删除整个泛型,创建一个通用的 Car 和 Truck 超类/协议,你就可以开始了——我认为泛型在这里没有用。它只会在问题之后产生问题。就错误消息而言,您必须指定func completionBlock&lt;T&gt;() ...,但这会产生预期和纠正错误等等,直到您最终调用getHandleResponseClosure(T),此时您将删除并使用您的代码。
  • 基本问题是 Car 和 Truck 与 T 无关,因此您无法转换它们。

标签: swift generics


【解决方案1】:

虽然您的代码还有其他问题,但最根本的问题是方法签名中的泛型类型必须直接在方法名称之后声明。看看下面的completionBlock。这段代码可以编译并运行。

struct Response<T, E: Error> {

}

struct Car {}
struct Truck {}

class BaseClass {

    func completionBlock<T>() -> ((Response<T, NSError>) -> ()) {
        return { response in /* What goes here? */ }
    }

}

let c = BaseClass()
let r: (Response<Car, NSError>) -> () = c.completionBlock()

顺便说一句,我会将struct Response&lt;T, E: Error&gt; 替换为...

enum Response<T> {
case success(T)
case error(Error)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2021-05-30
    • 2010-11-30
    • 2021-07-03
    相关资源
    最近更新 更多