Clojure «если» никогда не оценивает свой третий аргумент - PullRequest
7 голосов
/ 05 февраля 2009

Я уже некоторое время пытаюсь понять это как наше.

(defn is-decimal [astr]
  (if (. astr (indexOf (int \.)))
    (Double/parseDouble astr)
    (Integer/parseInt astr)))

Это функция, которую я написал. is-decimal либо передается что-то типа "2.5" или "5", либо что-то в этом роде, но он всегда использует второй аргумент if, а не третий. Я протестировал (. astr (indexOf (int \.))) в REPL, и он, кажется, работает нормально, он возвращает -1, если он не работает, и 1, если нет. Я считаю, что это может быть проблемой. -1 не означает ложь в Clojure. Кто-нибудь может придумать, как это исправить?

Заранее спасибо.

РЕДАКТИРОВАТЬ: Спасибо за помощь, ребята. Сразу после того, как я написал это, у меня появилась идея. Я написал предикатную функцию, которая проверяет 1 и -1. Как раз то, что мне было нужно. Я не должен писать код сразу после пробуждения: \

Ответы [ 3 ]

10 голосов
/ 06 февраля 2009

Если вы хотите проверить, содержит ли строка символ, вы можете использовать регулярное выражение:

(re-find #"\." astr)

Или:

(some #(= \. %) astr)

Или:

(contains? (into #{} astr) \.)

Или вы можете использовать includes? из clojure.contrib.seq-utils , который делает это тоже.

У Clojure уже есть читатель, который умеет различать целые и двойные числа, поэтому, если вы уверены, что ваша строка содержит только цифры, вы можете использовать ее. (Однако будьте осторожны, это читает что угодно, а не только цифры. Это потенциально опасно. Не используйте это, если есть вероятность, что в вашей строке есть что-то, кроме числа.)

Обратите внимание, Clojure также обрабатывает случай, когда целое число слишком велико, чтобы поместиться в нативный int без переполнения. Если вы хотите разобрать целые числа, вы можете посмотреть на функцию bigint вместо parseInt.

user> (class (read-string "2.5"))
java.lang.Double
user> (class (read-string "2"))
java.lang.Integer
user> (class (read-string "2000000000000"))
java.math.BigInteger

Если ваша функция является предикатом, в Clojure принято называть ее decimal? вместо is-decimal. На самом деле ваша функция - это больше анализатор чисел, поэтому лично я бы назвал это parse-number или string-to-number.

6 голосов
/ 05 февраля 2009

Непроверенные:

(if (> 0 (. astr (indexOf (int \.))))
2 голосов
/ 05 февраля 2009

хорошо, если он вернет -1, если не получится, тогда проверьте -1 и верните false, если он

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...