Nico
Nico

Reputation: 6359

Cannot convert value of type '(Int) -> Void' to expected argument type '(Any) -> Void'

I have two functions. The first one is taking an Integer as parameter and returns nothing:

func myIntFunction(_ arg: Int) -> Void {
    print(arg)
}

The second one is taking a function of type (Any) -> Void as parameter and returns nothing:

func myAnyFunction(arg: @escaping (Any) -> Void) {
    arg(5)
}

So there is something I am not catching here obviously as Int is a subset of Any right?

So if I trying to use this code:

myAnyFunction(arg: myIntFunction)

I get a compilation error:

Cannot convert value of type '(Int) -> Void' to expected argument type '(Any) -> Void'

and a suggestion to change my code into:

myAnyFunction(arg: myIntFunction as! (Any) -> Void)

But then I get a runtime error as (Int) -> Void cannot be casted into (Any) -> Void

What am I not getting there? I thought with a method/function asking for an argument of type Any, giving an Integer as argument would work.

Upvotes: 1

Views: 1107

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

So there is something I am not catching here obviously as Int is a subset of Any right?

Right. However, since Int is a subset of Any, a closure that expects Any can be passed an Int, but not the other way around (this cast is not possible either).

Imagine that it were possible to cast a closure taking an Int to a closure taking Any. Now the users would be able to pass an object other than Int to your closure, rendering type checking irrelevant. That is why casting among closure types like that is not allowed.

You can create another closure that calls myIntFunction, like this:

myAnyFunction(arg: {a -> Void in myIntFunction(a as! Int)})

Upvotes: 4

Related Questions