Skąd mogę wiedzieć, czy nazwa funkcji podana jako łańcuch może być wywołana czy nie w bieżącym kontekście? coś takiego:Clojure: ustal, czy istnieje funkcja
(callable? "asdasd") ;; false
(callable? "filter") ;; true
dzięki
Skąd mogę wiedzieć, czy nazwa funkcji podana jako łańcuch może być wywołana czy nie w bieżącym kontekście? coś takiego:Clojure: ustal, czy istnieje funkcja
(callable? "asdasd") ;; false
(callable? "filter") ;; true
dzięki
szukasz determinacji,
(resolve (symbol "asd"))
zwraca nil
(resolve (symbol "filter"))
return # 'clojure.core/filter
Aby sprawdzić, czy zmienna jest funkcją (zasługa @amalloy):
(-> s symbol resolve deref ifn?)
zwraca to, co powiedziałeś, ale jak mogę określić, czy można to wywołać, czy nie? – pistacchio
Możesz wywołać (fn? (Rozwiązać (symbol "filter"))) - Polecam to poprzez moją odpowiedź –
@JoostDiepenmaat: w tym przypadku '(fn? (Eval (symbol" filter ")))' - ' rozwiązać 'zwraca klasę lub var, nie coś z interfejsem' Fn' (zobacz moją odpowiedź), a zatem nie będzie działać. – ffriend
(defn callable? [name]
(clojure.test/function? (symbol name)))
UPD. Sprawdziłem, że fn?
sprawdza tylko dla interfejsu Fn
i nie działa dla rozpoznanego symbolu. Chociaż, clojure.test/function?
robi to, co jest potrzebne, więc zaktualizowałem przykład.
Szanse są, jeśli to potrzebne, robisz coś złego, ale ...
(defn callable?
[s]
(let [obj (try (eval (symbol s)) (catch Exception e))]
(and obj (fn? obj))))
Augh nr. Używanie 'resolve' oznacza, że możesz robić coś złego; użycie 'eval' do zrobienia tego samego zadania jest pewnym znakiem, że robisz coś złego. – amalloy
Również zwrócić uwagę na słowo „wpłacone” jest przeciążony jest tutaj. Wszystkie funkcje Clojure to java.util.concurrent.Callables. –