Pharo Smalltalk中=
和==
之间的区别是什么?它们的名称是什么,一个isEqual
和另一个?
= ~= equality / inequality (deep)
== ~~ equality / inequality (shallow)
答案 0 :(得分:2)
是的,==
是标识,它使用基元来比较指针是否指向同一个地址(即同一个对象)。
=
是相等的,意味着两个对象是相等的,尽管它们可能是两个不同的对象。默认情况下,=
使用==
,但可以重新实现。此外,当您重新实现=
时,建议您重新实现hash
,因此哈希集合不会变得疯狂
答案 1 :(得分:1)
需要考虑的一件重要事情是=
不仅在代码比较两个对象时显式使用。许多其他消息也会隐式使用消息=
,例如:includes:
,<=
,>=
,remove:
,{ {1}},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
Smalltalkers说a == b
和 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
也是=
,因为虚拟机会以特殊方式对其进行编码。
==
另一个有趣的案例是类n := 3 + 4.
m := 2 + 5.
n = m "true".
n == m "true".
Symbol
这是因为s := #symbol.
t := 'symbol' asSymbol.
s = t "true".
s == t "true!"
类确保环境中不会存在具有相同基础字符串的两个实例。
答案 2 :(得分:0)
TL; DR:=:“等于”,==:“与”相同
在对象&gt;&gt;#=
中= 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&gt;&gt;#==
中== anObject “原始。回答接收者和论证是否相同 对象(具有相同的对象指针)。不要重新定义消息== in 任何其他课程!必要。没有查找。不要在任何子类中覆盖。 请参阅对象文档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&gt;&gt;#= aDictionary “如果,两个词典是平等的 (a)他们是同一种“善良”的东西。 (b)他们有同一套钥匙。 (c)对于每个(共同)密钥,它们具有相同的值。 在更改“
之前,请参阅问题16760self == 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
方法。
`收集和GT;&GT; #hash “为接收器回答一个整数哈希值, - 未更改对象的哈希值随时间不变,并且 - 两个相等的对象具有相等的哈希值“
| hash |
hash := self species hash.
self size <= 10 ifTrue:
[self do: [:elem | hash := hash bitXor: elem hash]].
^hash bitXor: self size hash
` 自我大小&lt; = 10有一些气味,跟踪这些电话很有趣。
有关更多基本对象,请参阅:
玩得开心。
在Spotter中,hash #im
或= #im
会为您提供实施者列表,以便您快速了解相关信息。