在Pharo Smalltalk中,“=”和“==”有什么区别?它们的名称分别为“isEqual”和其他什么?
= ~= equality / inequality (deep)
== ~~ equality / inequality (shallow)
=
不仅在代码显式比较两个对象时使用。许多其他消息也会隐式使用消息 =
,例如: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
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!"
Symbol
类确保在环境中永远不存在具有相同底层字符串的两个实例。=
表示“等于”或“具有相同的值”。==
表示“完全相同”或“是同一对象”。 - lurker是的,==
是身份运算符,它使用原始类型来比较指针是否指向相同地址(即相同对象)。
=
是相等运算符,意思是两个对象相等,尽管它们可能是两个不同的对象。默认情况下,=
使用 ==
,但它可以重新实现。此外,当您重新实现 =
时,建议还重新实现 hash
,以便散列集合不会出错。
==
我会说:_检查它是否是同一对象_。 - Uko= 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
<primitive: 110>
self primitiveFailed
ProtoObject subclass:# Object
一个# =重写的例子是(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 在“有趣”方面实现了它)。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`
有趣的是它们共享相同的哈希
方法。
`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时,会有一些气味,尝试跟踪这些调用。
更多基本对象,请参见以下内容:
祝您探索愉快。
在Spotter中,hash #im
或= #im
会给出实现者列表,因此您可以快速了解它们。
xor
的哈希通常不是最优的,因为它们不使用比被xor
的元素中更高阶位的位。 - Leandro Caniglia
=
表示“相等”(两个对象的值相等),==
表示“恒等”(两个对象完全相同)。详见《Equality versus Identity》。 - lurker