2017-04-19 2 views
2

Supposons que files est une liste de Javas File dans Clojure et je souhaite obtenir une liste de noms de fichiers. Dans le REPL Leiningen je peux utiliser, par exemple,Clojure REPL, interop, Impossible de résoudre le symbole

(.getName (nth files 4)) 
=> "image.jpg" 

mais si j'utilise

(map .getName files) 

REPL jette un CompilerException java.lang.RuntimeException: Unable to resolve symbol: .getName in this context. Pourquoi donc?

je peux contourner ce problème avec

(defn gn [file] (.getName file)) 
(map gn files) 

mais je voudrais maintenant, s'il y a une façon plus élégante de la carte des méthodes Java aux listes dans Clojure.

Répondre

4

Vous pouvez soit utiliser memfn (dont certains disent que vous ne devriez pas utiliser, ne me rappelle pas pourquoi, commentaires bienvenus) ou tout simplement un lambda:

(map (memfn getName) files) ;;#1 
(map #(.getName %) files)  ;;#2 

comme pourquoi, bien parce que ce sont des méthodes et non des fonctions.

+2

A fait une recherche rapide du groupe Google, et il est ici, de Rich Hickey lui-même: ['memfn précédé #(), ce dernier étant maintenant préféré'] (https://groups.google.com/d/ msg/clojure/Xx-zt7LYzUI/kUQDg1DDNOsJ). – glts

+0

@glts merci, oui, j'ai également trouvé que les mêmes déclarations exactes dans les docs, mais je cherchais plus pour * pourquoi * il est préférable? – Shlomi

+0

Je l'ai lu comme 'memfn' maintenant simplement devenu une commodité inutile. Si la notation '#()' était là depuis le début, 'memfn' n'aurait pas été ajouté au noyau - donc ce ne serait peut-être pas une forte dépréciation. – glts