![](/img/trans.png)
[英]What is the difference between classVariableNames: '' and instanceVariableNames: '' when setting up a Singleton in Pharo Smalltalk?
[英]What is the difference between = and == in Pharo Smalltalk?
Pharo Smalltalk中=
和==
什么区别? 他们叫什么名字,一个是isEqual
,另一个是?
= ~= equality / inequality (deep)
== ~~ equality / inequality (shallow)
是的, ==
是标识,如果指针指向相同的地址(即相同的对象),它将使用原语进行比较。
=
是相等的,表示两个对象相等,尽管它们可能是2个不同的对象。 默认情况下, =
使用==
,但是可以重新实现。 另外,当您重新实现=
建议也重新实现hash
这样散列的集合就不会发疯
要考虑的一件事是=
不仅在代码比较两个对象时显式使用。 该消息=
也隐式地使用许多其他消息,例如: includes:
, <=
>=
, remove:
, keyAtValue:
indexOf:
upTo:
, peekFor:
occurrencesOf:
add:
(在Set
), at:
(以及at:ifAbsent:
和at:ifAbsentPut:
等的朋友),等等。
这意味着当您在类中重新定义=
,应确保
=
实现是可靠的(例如, banana = car
没有错误)并且 =
您还重新定义了hash
。 第一个条件的原因是能够比较任何两个对象,而发送方在发送=
消息之前不必特别注意。
第二个原因是,如果将来将您的对象用于哈希集合( Set
, Dictionary
, Bag
等),它们将兑现这些实体所需的重要不变式
IF a = b THEN a hash = b hash
考虑到确保hash
值是SmallIntegers
是一个很好的做法,可以说
IF a = b THEN a hash == b hash
换句话说,每当两个对象被认为相等时,它们的hash
值应被授予相同 。
命名
读取涉及=
的表达式(例如a = b
说a
等于 b
或a
等于 b
。
读取时a == b
Smalltalkers说a
和 b
是相同的对象 ,或a
是等于等于 b
或a
是相同的 a
或甚至a
等于-等于 b
。
进一步的评论
=
消息是特定于域的,这意味着您可以决定何时两个Smalltalk对象代表应用程序中的同一对象。
==
消息是系统功能,这意味着它由虚拟机(VM)实施,该虚拟机验证要比较的对象在内存中的位置是否完全相同。 换句话说,两个变量a
和b
在绑定到同一对象时是相等的 。
例子
a := 'This String'.
b := 'This' , ' ', 'String'.
a == b "false".
a = b "true"
f := 2 / 3.
g := 2 / 3.
f = g "true".
f == g "false"
一般来说, =
SmallInteger
也是==
因为VM会以特殊方式对其进行编码。
n := 3 + 4.
m := 2 + 5.
n = m "true".
n == m "true".
另一个有趣的情况发生在Symbol
类的实例上
s := #symbol.
t := 'symbol' asSymbol.
s = t "true".
s == t "true!"
发生这种情况是因为Symbol
类确保环境中不会存在两个具有相同基础字符串的实例。
TL; DR:=:“等于”,==:“与”相同
在对象中>>#=
= anObject
"Answer whether the receiver and the argument represent the same
object. If = is redefined in any subclass, consider also redefining the
message hash."
^self == anObject
在ProtoObject中>>#==
== anObject“ Primitive。回答接收方和参数是否是同一对象(具有相同的对象指针)。不要在任何其他类中重新定义消息==!必不可少。没有查找。请勿在任何子类中覆盖。请参见对象文档whatIsAPrimitive。”
<primitive: 110>
self primitiveFailed
因此,您可以覆盖=,但不能覆盖==。
FWIW ProtoObject subclass: #Object
#=替代的示例是
´= aBag“如果两个袋子(a)是相同的'事物',(b)它们的大小相同。(c)每个元素在两个袋子中出现相同的次数相同,则两个袋子相等。”
(aBag isKindOf: Bag) ifFalse: [^false].
self size = aBag size ifFalse: [^false].
contents associationsDo: [:assoc|
(aBag occurrencesOf: assoc key) = assoc value
ifFalse: [^false]].
^true`
与Dictionary
相比,它是完全不同的野兽(Bas以“有趣”的方式实现)。
'Dictionary >>#= aDictionary“如果两个字典相同,则(a)它们是相同的“种类”。(b)它们具有相同的键集。(c)每个(通用)键都具有相同的值。请参见问题16760,然后进行更改”
self == aDictionary ifTrue: [^true].
self species == aDictionary species ifFalse: [^false].
self size = aDictionary size ifFalse: [^false].
self associationsDo: [:assoc|
(aDictionary at: assoc key ifAbsent: [^false]) = assoc value
ifFalse: [^false]].
^true`
有趣的是,它们共享相同的hash
方法。
`Collection >>#hash“为接收方提供一个整数哈希值,以便-不变对象的哈希值随时间恒定,并且-两个相等的对象具有相等的哈希值”
| hash |
hash := self species hash.
self size <= 10 ifTrue:
[self do: [:elem | hash := hash bitXor: elem hash]].
^hash bitXor: self size hash
`自身大小<= 10时有些气味,跟踪这些呼叫很有趣。
有关更多基本对象,请参见以下内容:
祝您探索愉快。
在hash #im
, hash #im
或= #im
为您提供了实施者列表,因此您可以快速找到它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.