Is there a simple and definite way in Swift to check if something is a block / function being called? In some languages, this is a trivial thing, but maybe I look at it from the wrong point of view in Swift? Consider the following.
func foo(){ print("foo") } var bar: () -> () = { print("bar") } var baz: () -> (Bool) = { print("baz"); return true } print(foo) // (Function) print(bar) // (Function) print(baz) // (Function) print(foo is () -> ()) // true print(bar is () -> ()) // true print(baz is () -> ()) // false print(baz is () -> (Bool)) // true
Swift knows that they are all functions, although there is no such type of data. I can verify using a solid signature, but there may be a situation where I do not need a signature * and just want to call it. For instance:
func call(callable: () -> ()) { callable() } call(foo) // foo call(bar) // bar call(baz) // error: cannot convert value of type '() -> (Bool)' to expected argument type '() -> ()'
I can rewrite it in such a way that it will work for the return types of the Void and Bool types, but doing it for each type is crazy, especially since I do not care, but the compiler does ...
func call(callable: Any) { if let block: () -> () = callable as? () -> () { block() } else if let block: () -> (Bool) = callable as? () -> (Bool) { block() } } call(foo) // foo call(bar) // bar call(baz) // truely baz
* Agree, not caring about the signature, this is a sin. For argumentation, let's just not care about the return type.
source share