快速关闭不能覆盖任何 [英] swift closure cannot override Any

查看:53
本文介绍了快速关闭不能覆盖任何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许这是一个愚蠢的问题,但是我找不到任何解决方案.所以,我的问题是,有一个具有以下功能的事件发射器协议:

Maybe it's a stupid question, but I couldn't find any solutions yet. So, my problem is, that is have an event emitter protocol with a function like this:

mutating func on(eventName:String, action:((Any?)->())) {
    //..
}

我想使用它在事件触发时通知某些信息.例如,用于登录"事件的访问令牌.

And I want to use it to inform the listeners whenever an event is triggered with some information. Access token for the "login" event for example.

appSessionHadler.on("login") { (weak data: String?) in
    //...
}

然后我得到一个错误,即我无法使用该类型的参数列表调用"on".当然,它可以与Any一起使用:

And than I get an error, that I cannot invoke "on" with that argument list of type. Of course it works with Any:

appSessionHadler.on("login") { (weak data: Any?) in
    //...
}

一切都符合 Any ,所以我很困惑.有人可以解释一下!

Everything conforms to Any, so I'm a but confused. Can someone explain this, please!

我可以使用通用协议解决此问题,但仍然令我感到沮丧的是,它不能像这样工作.

推荐答案

您在保证编译器无法遵守. on 函数可以随意调用任何类型的数据的 action .但是您传递的函数仅接受 String .如果 on 上包含(直接或间接)以下代码,系统应该怎么做:

You're making a promise the compiler can't keep. The on function is free to call action with any kind of data at all. But the function you passed only accepts String. What is the system supposed to do if on includes the following code (directly or indirectly):

action(1)

1 不是 String ,因此类型安全性将被破坏.编译器不允许您这样做.

1 is not a String, so type safety would be broken. The compiler can't let you do that.

对此考虑的另一种方法是,上的具有类型为 F 的函数,并且您传递的是 supertype F ,而不是 F 子类型. String Any 的子类型.但是函数参数以相反的顺序工作.(String)-> Void (Any)-> Void 的超类型.因此,这与将 Any 类型的变量传递给需要 String 的函数相同.形式上,我们说函数的参数是互变的,而返回值是协变的.您可以在 Swift中的类型差异中了解更多内容.

Another way to think about this is that on takes a function of type F, and you are passing a supertype of F rather than a subtype of F. String is a subtype of Any. But function parameters work in the reverse order. (String)->Void is a supertype of (Any)->Void. So this is the same as passing a variable of type Any to a function that requires String. Formally we say that functions are contravariant in their parameters and covariant in their return values. You can read more on that in Type Variance in Swift.

您怀疑,在这里泛型是正确的答案.任何几乎总是错误的工具.而且 Any?是Swift中最难使用的类型之一,因此我绝对会不惜一切代价避免使用该类型.( Optional 本身是 Any 的子类型,而Swift会自动升级为 Optional ,因此当您拥有 Any?来开始获得Double Optionals,甚至更糟.)

As you suspect, generics are the right answer here. Any is almost always the wrong tool. And Any? is one of the hardest types to work with in Swift, so I'd definitely avoid that one at all costs. (Optional is itself a subtype of Any, and Swift has automatic promotion to Optional, so it is very common when you have Any? to start getting double Optionals and worse.)

这篇关于快速关闭不能覆盖任何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆