Prüfen Sie, ob die Variable ein Block / eine Funktion / eine aufrufbare Variable in Swift ist

Gibt es in Swift eine einfache und eindeutige Möglichkeit, um zu überprüfen, ob es sich bei etwas um einen aufrufbaren Block / eine aufrufbare Funktion handelt? In manchen Sprachen ist das eine Kleinigkeit, aber vielleicht sehe ich das in Swift aus einer falschen Perspektive? Folgendes berücksichtigen

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 weiß, dass es sich um alle Funktionen handelt, obwohl es keinen solchen Datentyp gibt. Ich kann mit einer festen Signatur prüfen, aber es kann vorkommen, dass mir die Signatur nicht wichtig ist* und möchte es einfach aufrufen. Beispielsweise

func call(callable: () -> ()) {
    callable()
}

call(foo) // foo
call(bar) // bar
call(baz) // error: cannot convert value of type '() -> (Bool)' to expected argument type '() -> ()'

Ich kann es so umschreiben, das wird für @ funktionierVoid undBool gibt Typen zurück, aber dies für jeden Typ zu tun ist verrückt, zumal es mir egal ist, aber der Compiler tut es ...

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

* Stimme zu, sich nicht um die Unterschrift zu kümmern ist eine Sünde. Für das Argument ist der Rückgabetyp einfach egal.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage