繁体   English   中英

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:等的朋友),等等。

这意味着当您在类中重新定义= ,应确保

  1. 您对=实现是可靠的(例如, banana = car没有错误)并且
  2. 每次您重新定义=您还重新定义了hash

第一个条件的原因是能够比较任何两个对象,而发送方在发送=消息之前不必特别注意。

第二个原因是,如果将来将您的对象用于哈希集合( SetDictionaryBag等),它们将兑现这些实体所需的重要不变式

      IF a = b THEN a hash = b hash

考虑到确保hash值是SmallIntegers是一个很好的做法,可以说

      IF a = b THEN a hash == b hash

换句话说,每当两个对象被认为相等时,它们的hash值应被授予相同


命名

读取涉及=的表达式(例如a = ba 等于 ba 等于 b

读取时a == b Smalltalkers说a b 是相同的对象 ,或a 是等于等于 ba 是相同的 a或甚至a 等于-等于 b

进一步的评论

=消息是特定于域的,这意味着您可以决定何时两个Smalltalk对象代表应用程序中的同一对象。

==消息是系统功能,这意味着它由虚拟机(VM)实施,该虚拟机验证要比较的对象在内存中的位置是否完全相同。 换句话说,两个变量ab在绑定到同一对象时是相等的

例子

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时有些气味,跟踪这些呼叫很有趣。

有关更多基本对象,请参见以下内容:

Magnitude >>#hash实现者

祝您探索愉快。

hash #imhash #im= #im为您提供了实施者列表,因此您可以快速找到它们。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM