web-dev-qa-db-fra.com

ClassCastException Java.lang.Long ne peut pas être converti en clojure.lang.IFn

J'ai une fonction qui prend le nombre d'années et le salaire, puis double récursivement le salaire jusqu'à épuisement des années. Cependant, je continue à recevoir cette erreur:

ClassCastException Java.lang.Long ne peut pas être converti en clojure.lang.IFn

Le code

(defn calculate-salary
    [years salary]
    (if (= years 0)
        (salary)
        (calculate-salary (- years 1) (* salary 2))))

Je suis très nouveau à Clojure, donc je suis sûr que c'est quelque chose de simple, mais je n'arrive pas à le comprendre.

33
Jack Slingerland

La signification de l'erreur ne devrait pas être trop difficile à trier: un nombre est utilisé là où une fonction est attendue.

Les parenthèses dans Clojure ne sont pas une construction de regroupement, elles sont principalement utilisées pour appeler des appels de fonction. Si vous changez (salary) à salary vous retournerez le numéro plutôt que d'essayer de l'appeler comme une fonction sans argument.

41
noisesmith

Depuis que vous êtes nouveau, j'ai réécrit votre fonction pour qu'elle soit un peu plus idiomatique. En outre, il utilise recur afin de ne pas consommer la pile d'appels.

(defn calculate-salary
  [years salary]
  (if (zero? years)
    salary
    (recur (dec years) (* salary 2))))

Remarquez l'utilisation du zéro? prédicat, récurrent et dec

EDIT: fautes de frappe et grammaire

7
RedDeckWins

Cette

(salary)

est un appel de fonction, mais salary n'est pas une fonction - c'est un nombre.

La solution est de ne pas le mettre entre parenthèses:

(if (= years 0) salary (calculate-salary (- years 1) (* salary 2)))
6
mipadi

Vous devez supprimer les crochets d'environ salary dans votre condition if:

(if (= years 0)
        salary
        (calculate-salary (- years 1) (* salary 2))

la forme (f arg1 arg2 ..) tente d'appeler f en tant que fonction avec arg1, arg2 ... comme arguments. Par conséquent (salary) tente d'appeler salary (un long) en tant que fonction sans argument, d'où l'erreur.

4
Lee