Swift强制转换泛型而不知道类型

时间:2016-10-28 12:07:03

标签: ios swift xcode

是否有可能对类似的对象进行类型转换(让代码说明一下):

protocol Parent {
    ...
}

class Child<LiterallyAnyValue, SameAsThePrevious>: Parent {
    ...
}

然后使用它时:

func foobar(parent: Parent) {
    if parent is Child { //ONE
        print(parent as! Child) //TWO
    }
}

在签名点上xcode要我提供两种类型的&#34; Child&#34;在&lt;&gt;内像Child&lt; Int,String&gt; ...

问题在于那些类型可能是任何东西......很明显 (而且我已经尝试过Child&lt; Any,Any&gt;但在这种情况下并不起作用)

是否有解决方法或解决方案?

--------澄清--------

我正在开发一个iOS 7项目,所以我无法真正使用任何现代库:) 这包括PromiseKit和Alamofire,该应用程序必须提出大量的http请求。请求中的使用承诺在我身上发展,所以我创建了自己的Promise类。

起初我做了这样,Promise类不是通用的,它会接受Any吗?作为解决程序的价值 在那之后我想用类型澄清来改进我的小Promise类,所以Promise类成为&#34;类Promise&lt; T&gt;&#34;

在我的实现中,then方法创建了一个PromiseSubscriber,然后将其存储在名为subscriber的Promise属性中。

PromiseSubscriber是这里的协议,它有两个子集类,一个是PromiseHandler(这是在解析promise时调用的),另一个是PromiseCatcher(当promise被拒绝时调用)

PromiseSubscriber子集类都有一个名为promise的属性和一个名为handler的属性 这些类也是泛型,因此您可以知道它们存储的Promise类型以及处理程序的返回类型。

在我的解决过程中,我必须检查PromiseSubscriber是否是一个(让我们说)PromiseHandler,如果它然后调用返回一些东西的处理程序,然后用该值解析订阅的promise。

这就是问题所在。我无法检查订户是捕手还是处理者......

我希望现在已经足够清楚了。也许这不是正确的方法,老实说我不知道​​我只是想创造一些有趣且易于使用的东西(代码完成而不检查类型)。

如果它仍然不清楚,你愿意帮助我,我会发送课程!

2 个答案:

答案 0 :(得分:1)

要理解你在这里真正要做的事情有点困难(请告诉我它不是JSON解析;我对JSON解析感到厌倦,而且这是人们唯一要问的问题),但是简短的回答几乎肯定没有。其中一些部分可能是对类型的滥用,其中一部分是Swift的当前限制。

为了专注于Swift部分的限制,Swift缺乏更高级的类型。谈论Array是不可能的。这不是Swift中的类型。您只能使用Array<Int>Array<String>甚至Array<T>,但仅限于在编译时可以确定T的情况。有几种方法可以解决这个问题,但这实际上取决于你的潜在问题。

对于类型方面的滥用,你通常不应该在Swift中拥有if x is ...。在绝大多数情况下,这应该通过协议来解决。无论您要在if中执行什么操作,请将其作为Parent协议的一部分,并为其提供默认的空实现。然后在Child中覆盖该实现。例如:

protocol Parent {
    func doSpecialThing()
}

extension Parent {
    func doSpecialThing() {} // nothing by default
}

class Child<LiterallyAnyValue, SameAsThePrevious>: Parent {}

extension Child {
    func doSpecialThing() {
        print(self)
    }
}

func foobar(parent: Parent) {
    parent.doSpecialThing()
}

感谢您的澄清;承诺是一件很棒的事情。你的错误就在这里:

  

在我的解决过程中,我必须检查PromiseSubscriber是否是一个(比方说)PromiseHandler,如果它然后调用返回一些内容的处理程序,然后用该值解析订阅的promise。

您的解决过程不应该知道它是处理程序还是捕手。如果是这样,那么您的PromiseSubscriber协议定义不正确。听起来你错过的那一块是结果。大多数Promise类型都建立在Result之上,这是一个枚举捆绑成功或失败。在您的方案中,处理程序将处理成功的结果并忽略失败的结果。捕手将处理失败的结果并忽略成功的结果。但承诺解决方案应该不在乎。它应该只将结果发送给所有订阅者,让他们做他们做的事情。

您可以使用上述协议在没有Result类型的情况下构建它。

protocol PromiseSubscriber {
    associatedType Wrapped // <=== It's possible you've also missed this piece
    func handleSuccess(value: Wrapped)
    func handleFailure(failure: Error)
}

extension PromiseSubscriber {
    func handleSuccess(value: Wrapped) {} // By default do nothing
    func handleFailure(failure: Error) {} 
}

class PromiseHandler<Wrapped> {
    func handleSuccess(value: Wrapped) { ... do your thing ... }
}

class PromiseCatcher {
    func handleFailure(failure: Error) { ... do your thing ... } 
}

我建议学习PinkyPromise。这是一个很好的,简单的Promise库(与PromiseKit不同,它增加了很多可以让它更难理解的东西)。我可能不会在这里使用协议;关联类型使事情变得更难,我认为你没有太多的东西。我会用Result。

答案 1 :(得分:0)

在foobar函数中使用泛型类型,下面的那个要求parent参数符合Parent协议,T表示传递的对象的类。

func foobar<T: Parent>(parent: T) {
    print(parent)
}