Pharo Smalltalk中=和==有什么区别?

时间:2017-01-16 21:05:11

标签: smalltalk pharo

Pharo Smalltalk中===之间的区别是什么?它们的名称是什么,一个isEqual和另一个?

= ~=    equality / inequality (deep)
== ~~   equality / inequality (shallow)

3 个答案:

答案 0 :(得分:2)

是的,==是标识,它使用基元来比较指针是否指向同一个地址(即同一个对象)。

=是相等的,意味着两个对象是相等的,尽管它们可能是两个不同的对象。默认情况下,=使用==,但可以重新实现。此外,当您重新实现=时,建议您重新实现hash,因此哈希集合不会变得疯狂

答案 1 :(得分:1)

需要考虑的一件重要事情是=不仅在代码比较两个对象时显式使用。许多其他消息也会隐式使用消息=,例如:includes:<=>=remove:,{ {1}},keyAtValue:indexOf:upTo:peekFor:occurrencesOf:add:),Set(和朋友at:at:ifAbsent:等)以及其他许多人。

这意味着当您在班级中重新定义at:ifAbsentPut:时,您应该确保

  1. =的实施非常强大(例如,=没有错误)
  2. 每次重新定义banana = car时,您也会重新定义=
  3. 第一个条件的原因是能够比较任何两个对象,而发送者在发送hash消息之前不必特别小心。

    第二个原因是,如果将来您的对象用于散列集合(=SetDictionary等),他们将尊重重要的不变量这些实体要求

    Bag

    鉴于确保 IF a = b THEN a hash = b hash 值为hash是一种非常好的做法,可以说

    SmallIntegers

    换句话说,每当两个对象被认为相等时,他们的 IF a = b THEN a hash == b hash 值应该被授予相同的

    <强>命名

    在阅读涉及hash的表达式时,例如=,表示a = b 等于 ab 等于 a

    阅读b Smalltalkers说a == b a 是同一个对象b 等于 ab 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)对于每个(共同)密钥,它们具有相同的值。     在更改“

之前,请参阅问题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方法。

`收集和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有一些气味,跟踪这些电话很有趣。

有关更多基本对象,请参阅:

Magnitude>>#hash implementers

玩得开心。

在Spotter中,hash #im= #im会为您提供实施者列表,以便您快速了解相关信息。

enter image description here