swift closure cannot override Any

有些话、适合烂在心里 提交于 2021-01-27 13:10:37

问题


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
    //...
}

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
    //...
}

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

I could solve this with a Generic protocol, but it still frustrates me that it does not works like this.


回答1:


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 is not a String, so type safety would be broken. The compiler can't let you do that.

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.

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.)



来源:https://stackoverflow.com/questions/35697569/swift-closure-cannot-override-any

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!