没有指定泛型类型的Swift强制转换

时间:2016-08-04 23:51:14

标签: swift generics casting bolts-framework

我正在尝试为我的应用程序创建一个通用错误处理程序,并使事情变得更加复杂我正在使用事件总线来传递任务,因此我无法在编译时指定类型。我正在尝试执行以下操作:

let apiTask = data.object as! Task // Option 1
let apiTask = data.object as! Task<AnyObject> // Option 2

apiTask!.continueWith { (task) in
    if(task.cancelled || task.faulted) {
        self.isInError = true
    } else {
        self.isInError = false
    }
}

选项1 给出编译时错误,指出无法推断任务的泛型类型TResut。 选项2 会导致运行时错误Task<SpecificType> cannot be caster to Task<AnyObject>

我在Java中有相同的实现,似乎你不需要在那里指定泛型类型。 Task<TResult>可能是任何类型,因此我无法在上述方法中指定它。有什么方法可以解决这个问题吗?

3 个答案:

答案 0 :(得分:2)

听起来你实际上并不想要通用类型。存在通用类型,以便在编译时指定您要擦除的类型信息。如果您几乎总是想忽略泛型参数,那么您应该创建一个非泛型类型。但是,如果您通常使用该信息,您仍然可以在某些方法中忽略它:您只需要将这些方法设为通用:

func doSomething<T>(to: Task<T>) {
    //Do whatever you want that doesn't involve `T`.
    //You still have to make this method generic so it accepts any type of `Task`.
}

答案 1 :(得分:0)

您是否考虑过将任务作为协议(或符合协议)?

y

答案 2 :(得分:0)

我在Bolts-Swift问题跟踪器上看到了你的帖子,因为我不知道你是否在那里看到我的答案,我想我也在这里发布了它。我是Bolts的新手,也是Swift的初学者,但我有几年作为程序员的经验,所以这是我提出的一个可能的解决方案:

我认为你可以创建一个类或结构来充当你实际结果的包装器。这个struct / class只需要一个AnyObject类型的变量。然后,您可以将其用作任务的通用类型。稍后您可以对结果e的类型进行实际检查。 G。使用if let string = task.result?.result as? String{...}。请参阅下面的代码以了解我的意思。

func printHelloWorld() {
    doSomething().continueWith() { task in
        print(task.result?.result)
    }
}

func doSomething() -> Task<MyResult> {
    let tcs = TaskCompletionSource<MyResult>()
    ...
    tcs.set(result: MyResult(result: "Hello World" as AnyObject))
    ...
    return tcs.task
}

struct MyResult {
    var result: AnyObject
}

正如我所说,我是Bolts和Swift的初学者,可能还有更好的解决方案。如果您已经找到了更好的解决方案,也许您可​​以在此处发布并选择它作为您问题的答案。 :)