Странная ошибка при попытке сопоставить parseInt в Clojure
Я изучаю Clojure, и у меня есть сомнения:
Почему при вводе
(map vector '("1" "2" "3"))
Я получаю (["1"] ["2"] ["3"])
Это нормально, потому что vector
- это функция (или почти я думаю), и я могу сделать
(vector "3")
и получите ["3"]
.
Пока все хорошо, но когда я пытаюсь
(map Integer/parseInt '("1" "2" "3"))
Я получаю сообщение об ошибке. Не следует ли parseInt
вести себя как функция?
Затем мне нужно ввести
(map #(Integer/parseInt %) '(......
Почему я не могу использовать parseInt
как функцию? Для меня это функция, и я могу использовать ее как
(Integer/parseInt "3")
Я чувствую, что это немного некогерентно, но я уверен, что ошибаюсь, и для этого я прошу...
Ответы
Ответ 1
Вы должны обернуть его в #()
или (fn ...)
. Это связано с тем, что Integer/parseInt - это метод Java, и методы Java не могут быть переданы. Они не реализуют интерфейс IFn
.
Clojure построен на Java, и иногда это протекает, и это один из этих случаев.
Ответ 2
Как утверждали другие, вам нужно обернуть Integer/parseInt, чтобы преобразовать его из Java-метода в функцию Clojure:
(map #(Integer/parseInt %) '("1" "2" "3"))
Причиной этого является то, что функции Clojure должны реализовывать интерфейс IFn для передачи в качестве аргументов в функции более высокого порядка, такие как map
.
Это немного уродливо, если вы делаете такое преобразование много раз, поэтому я бы рекомендовал обернуть вашу функцию parse-int следующим образом:
(defn parse-int [s] (Integer/parseInt s))
(map parse-int '("1" "2" "3"))
В качестве окончательной альтернативы вы можете использовать встроенную функцию read-string - это вернет целые числа в вашем случае, но также будет работать и для удвоений и т.д.:
(map read-string '("1" "2" "3"))
Ответ 3
Посмотрите на вопрос о переполнении стека Преобразование последовательности строк в целые числа (Clojure). В ответ говорится: вы должны обернуть Integer/parseInt в анонимной функции, потому что методы Java не являются функциями.