Clojure REPL, взаимодействие, невозможно разрешить символ

Предположим, что files — это список Java File в Clojure, и я хочу получить список имен файлов. В Leiningen REPL я могу использовать, скажем,

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

но если я использую

(map .getName files)

REPL выдает CompilerException java.lang.RuntimeException: Unable to resolve symbol: .getName in this context. Почему это?

Я могу обойти эту проблему с помощью

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

но я хотел бы узнать, есть ли более элегантный способ сопоставления методов Java со списками в Clojure.


person Berg    schedule 19.04.2017    source источник


Ответы (1)


Вы можете использовать memfn (некоторые говорят, что вам не следует использовать, не помню почему, комментарии приветствуются ) или просто лямбда:

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

а почему, ну потому что это методы, а не функции.

person Shlomi    schedule 19.04.2017
comment
Выполнил быстрый поиск в группе Google, и вот он, от самого Рича Хики: 'memfn предшествовал #(), последний теперь предпочтительнее'. - person glts; 19.04.2017
comment
@glts спасибо, да, я также нашел точно такие же утверждения в документах, однако я больше искал почему это предпочтительнее? - person Shlomi; 19.04.2017
comment
Я прочитал это как memfn сейчас, просто ставшее ненужным удобством. Если бы нотация #() существовала с самого начала, memfn не было бы добавлено в ядро, так что это не могло бы быть серьезным устареванием. - person glts; 19.04.2017
comment
Красиво, я так и думал. Так что дело не в том, что это неправильно, это просто избыточно. - person Shlomi; 19.04.2017