Czy w Swift istnieje prosty i określony sposób sprawdzenia, czy coś jest blokowalnym blokiem/funkcją? W niektórych językach jest to rzecz trywialna, ale może patrzę na to z niewłaściwej perspektywy w Swift? Rozważ następujące.Sprawdź, czy zmienna jest blokiem/funkcją/wywoływaną w Swift
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 wie, że wszystkie są funkcjami, chociaż nie istnieje taki typ danych. Mogę sprawdzić za pomocą stałego podpisu, ale może być sytuacja, w której nie interesuje mnie podpis * i po prostu chcę go wywołać. Na przykład:
func call(callable:() ->()) {
callable()
}
call(foo) // foo
call(bar) // bar
call(baz) // error: cannot convert value of type '() -> (Bool)' to expected argument type '() ->()'
mogę przepisać go w ten sposób, który będzie pracować dla Void
i Bool
rodzajów powrotów, ale robi to dla każdego typu jest szalony, zwłaszcza, że nie dbam o to, ale kompilator robi ...
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
* Zgadzam się, nie dbając o podpisie jest grzechem. Dla argumentu nie zwracajmy uwagi na typ zwrotu.
Chyba problem do rozważenia byłoby, że nie tylko trzeba wiedzieć, jeśli zmienna była wymagalne, ale jeśli oczekuje parametrów. Świadomość, że coś można wywołać, nie ma żadnej wartości, jeśli nie znasz jego parametrów. –
To prawda, stąd przypis. –
Ale nie mówię o typie zwrotu. Mówię o parametrach. –