问题描述
我想在 Squeak 中制作一个简单的程序来计算几个点之间的距离,但我不想使用已经定义的类 Point。到目前为止,我有以下内容:
x 和 y 的 getter 和 setter 方法已自动生成:
x ^ x
x:一个对象 x := anObject。
我编写的距离方法如下:
system.in
现在我打开一个工作区并尝试打印结果:
distance:aPoint
"comment stating purpose of message"
|dx dy |
dx:=aPoint x - x.
dy:=aPoint y - y.
^ (dx*dx+dy*dy) sqrt.
但我得到的结果如下:
我错过了什么?
解决方法
尝试替换以下内容:
obj1 x:3 y:4.
有了这个:
obj1 x:3; y:4.
基本上,您正在发送消息 #x:y:
,但您没有具有该名称的方法。相反,您有一个方法 #x:
和另一个方法 #y:
,因此您需要对同一个对象进行两次单独的调用(使用 cascade 运算符({{1 }}).
注意优先级
在您的方法 distance: aPoint
中,您将勾股距离计算为
(dx*dx + dy*dy) sqrt
虽然这个公式在通常的数学符号和大多数编程语言中都是正确的,但在 Smalltalk 中它的工作方式有所不同。实际上它会产生与
相同的结果((dx*dx + dy)*dy) sqrt,
这不是你想要的。这样做的原因是在 Smalltalk 中 #*
和 #+
都是具有相同优先级的二元运算符。因此,你应该写
((dx*dx) + (dy*dy)) sqrt
相反,或等效
(dx*dx + (dy*dy)) sqrt
因为您只需要确保 dy*dy
是 #+
的参数。
实现相同目标的更优雅的方法是
(dx squared + dy squared) sqrt.
此外,如果您查看 Point
类,您会发现极坐标中的 #r
方法可以在您编写时提供所需的结果
(dx @ dy) r.