Замыкание нахождения прямоугольника - PullRequest
1 голос
/ 05 февраля 2020
(defn -main []
  (println "\nTo compute the area of a rectangle,")
  (print   " enter its width: ") (flush)
  (let [ Width (read) ]
    (assert (>= Width 0) "-main: Width must be positive"))
  (print " enter its height: ") (flush)
  (let [ Height (read) ]
    (assert (>= Height 0) "-main: Height must be positive")
    (printf "\nThe area is %f %f\n\n" (rectangleArea Width Height  ))

Я новичок в Clojure, и мне не удается разрешить ошибку символа всякий раз, когда я пытаюсь скомпилировать функцию printf

Ответы [ 2 ]

4 голосов
/ 05 февраля 2020

Хотя вы предоставили неполный пример, после нескольких изменений кажется, что ваша проблема в том, что вы используете %f для форматирования целого числа (java .lang.Long):

(defn -main []
  (println "\nTo compute the area of a rectangle,")
  (print   " enter its width: ") (flush)
  (let [ Width (read) ]
    (assert (>= Width 0) "-main: Width must be positive"))
  (print " enter its height: ") (flush)
  (let [ Height (read) ]
    (assert (>= Height 0) "-main: Height must be positive")
    (printf "\nThe area is %f %f\n\n" (+ 10 20  ))))

(-main)
;;=> 
1. Unhandled java.util.IllegalFormatConversionException
   f != java.lang.Long

И, конечно, ваши блоки let некорректны, поэтому это должно быть примерно так:

(defn- read-size [label]
  (print  " enter its " label ":")
  (flush)
  (let [num (read)]
    (assert (>= num 0) (str  label " must be positive"))
    num))

(defn -main []
  (println "\nTo compute the area of a rectangle,")
  (flush)
  (let [width (read-size "width")
        height (read-size "height")]
    (printf "\nThe area is %d \n\n" (* width height))))

1 голос
/ 06 февраля 2020

Ваш тест - основная программа, стиль C. Не делай этого. Напишите вашу программу как именованные функции и используйте REPL для их осуществления. Для начала, это отделяет ошибки компиляции от ошибок выполнения.

Я назвал вашу функцию area. Первая кровь, отобранная компилятором, ...

Syntax error compiling at (amuse.clj:24:39).
Unable to resolve symbol: rectangleArea in this context

Совершенно верно. Вы не указали let или def значение для rectangleArea. Удаление и повторная попытка приводит к аналогичной ошибке:

Syntax error compiling at (amuse.clj:24:39).
Unable to resolve symbol: Width in this context

Проблема в том, что, как заметил Джурай Мартинка , вы находитесь за пределами привязки let для Width, когда вы ссылаетесь к этому. Удаляя Width, мы получаем чистую компиляцию. Давайте попробуем вызвать функцию:

=> (area)

To compute the area of a rectangle,
 enter its width: 8
 enter its height: 9
Execution error (ClassCastException) at amuse/area (amuse.clj:24).
java.lang.Long cannot be cast to clojure.lang.IFn

Что происходит? Вызов printf оценивает выражение (Height), которое в этом случае пытается вызвать номер 8.0 как функцию.

Старайтесь также избегать взаимодействия ввода / вывода в ваших функциях. Аргументы и результаты лучше. Вы можете использовать аргументы ключевого слова и возвращать карты, чтобы передать смысл. Ваша функция может быть написана ...

(defn area [& {:keys [height width]}]
  {:area (+ height width)})

Это выглядит странно, но легко в использовании:

=> (area :height 8 :width 9)
{:area 17}

Это правильно? Я так не думаю. Мы должны умножить, а не добавить:

(defn area [& {:keys [height width]}]
  {:area (* height width)})
amuse=> (area :height 8 :width 9)
{:area 72}

Таким образом, наша функция по сути является синонимом *.

Если бы я был на вашем месте, я бы позволил REPL сейчас принять на себя всю ответственность за подтверждение. Если у вас есть серьезная работа, вы найдете Clojure spe c очень удобным.

Всего наилучшего.

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