2016-11-20 6 views
2

Я изучаю Smalltalk несколько дней назад, и я работаю над проектом, который в основном находит область и периметр для класса окружности, который реализуется из класса Shape. Другими словами, Shape - суперкласс для Circle.Как умножить целое число с значениями float в Smalltalk

Когда я запускаю свой код, я получил сообщение об ошибке «числовой примитивный ожидаемый числовой аргумент, полученный». Я считаю, что ошибка возникает, потому что я умножаю целое число с значением float. Я не знаю, как исправить ошибку, поэтому, если кто-то может дать мне несколько предложений?

P.S - Я использую usmalltalk, который является конкретной версией Smalltalk, но имеет те же функции.

(class Shape Object 
    (Perimeter Area) 
    (method getPerimeter() Perimeter) 

    (method setPerimeter:(Perim) 
     (set Perimeter Perim) 
    ) 


    (method CreateShape::(Perim Ar) 
     (set Perimeter Perim) 
     (set Area Ar) 
     self 
    ) 

    (class-method NewShape:: (Perimeter Area) 
     (CreateShape:: (new self) Perimeter Area) 
    ) 
) 


(class Circle Shape 
    (Radius) 

    (method getRadius() Radius) 

    (method setRadius:(radi) 
     (set Radius radi) 
     (set Perimeter (* (* 2 (asFloat (/ 22 7))) Radius)) #The error exits here 
     (set Area (* (* (asFloat (/ 22 7)) Radius) Radius)) 
    ) 

    (method CreateCircle:(radi) 
     (set Radius radi) 
     self 
    ) 

    (class-method NewCircle: (Radius) 
     (CreateCircle: (new self) Radius) 
    ) 

) 
+1

Где вызывается 'setRadius'? –

+0

@ScottHunter, когда я вызываю setRadius в классе Circle, будет обновлять Perimeter и Area (используя Shape) для класса Circle, используя уравнение (показано) – harrisonthu

+0

Сообщение об ошибке на самом деле означает, что вы пытаетесь размножаться пустой строкой. . –

ответ

4

Smalltalk диалект используется не следует обычный синтаксис Smalltalk, поэтому позвольте мне перевести выражение обижая в более знакомую один.

Разберет Выражение

(* (* 2 (asFloat (/ 22 7))) Radius) 

В дальнейших, выражении справа от --> является обычной формой выражения слева.

Шаг 1:

/ 22 27 --> 22/27 

Шаг 2:

asFloat(/ 22 7) --> (22/27) asFloat 

Шаг 3:

* 2 (asFloat (/ 22 27)) --> 2 * (22/27) asFloat 

Шаг 4:

* (* 2 (asFloat (/ 22 27)) Radius) --> (2 * (22/27) asFloat) * Radius 

Поэтому ошибка здесь означает, что Radius не является числом. Как было предложено в комментариях, проблема в том, что переменной Radius не присвоено надлежащее (то есть числовое) значение, и это то, что сообщение об ошибке как-то пытается сказать.

Конечно, переменная Radius принимает свое значение от аргумента radi, отправленного по методу setRadius:. Это означает, что происхождение проблемы находится в отправителе setRadius:. Но здесь анализ исходного кода становится сложным, потому что он статический и не показывает последовательность шагов при выполнении вашей программы.

Лучшим подходом к пониманию проблемы является динамический один. В Smalltalk вы делаете это с помощью отладчика. Я не знаком с диалектом Smalltalk, который вы используете, но когда появляется ошибка, вам следует предложить способ отладки вашего кода. Примите эту опцию и просмотрите список сообщений, которые были отправлены непосредственно перед сообщением об ошибке. После определения метода, который оценивает выражение на шаге 4, проверьте значение переменной Radius и посмотрите, что там находится. Это не должно быть число, иначе не было бы никакой ошибки. Оттуда вы сможете проследить до места, где формальный аргумент radi получает свое фактическое значение, что приводит к корню проблемы.

Последнее замечание. Ваш вопрос читается Как умножить целые числа с поплавками в Smalltalk.Ответ просто умножьте их, используя *. Smalltalk выяснит, как это сделать. Вам не нужно отправлять какие-либо конверсионные сообщения, такие как asFloat или тому подобное (вы можете удалить их из своего кода, чтобы упростить его.) Динамическое типирование Smalltalk освобождает программиста от времени, затрачиваемого на переменные типа. Не потому, что в компиляторе есть какая-то магия, но из-за полиморфности языка.