首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Pharo Smalltalk中=和==有什么区别?

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

Stack Overflow用户
提问于 2017-01-17 05:05:11
回答 3查看 3.1K关注 0票数 3

在Pharo Smalltalk中,===有什么不同?它们的名称是什么,一个isEqual和另一个?

代码语言:javascript
复制
= ~=    equality / inequality (deep)
== ~~   equality / inequality (shallow)
EN

回答 3

Stack Overflow用户

发布于 2017-01-17 06:07:04

是的,==是identity,它使用一个原语来比较指针是否指向相同的地址(即相同的对象)。

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

票数 3
EN

Stack Overflow用户

发布于 2017-01-17 09:44:20

需要考虑的一件重要事情是,=不仅在代码比较两个对象时显式使用。消息=还被许多其他消息隐含地使用,例如:includes:<=>=remove:keyAtValue:indexOf:upTo:peekFor:、D10、D11(在D12中)、D13(以及朋友D14、D15等)和许多其他消息。

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

  1. 您的=实现是健壮的(例如,banana = car不会产生错误)和
  2. 每次您重新定义=时,您也会重新定义e.g.

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

第二个原因是如果将来在散列集合(SetDictionaryBag等)中使用您的对象。它们将遵守这些实体所需的重要不变量

代码语言:javascript
复制
      IF a = b THEN a hash = b hash

考虑到确保hash值为SmallIntegers是一种非常好的实践,可以这样说

代码语言:javascript
复制
      IF a = b THEN a hash == b hash

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

命名

当读取涉及=的表达式时,比如a = b,有人会说a等于b,或者a等于b

当阅读a == b时,Smalltalkers会说ab是同一个对象,或者a等同于b,甚至a等于b

进一步评论

=消息是特定于域的,这意味着当两个Smalltalk对象在您的应用程序中表示完全相同的对象时,应由您决定。

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

示例

代码语言:javascript
复制
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以一种特殊的方式对它们进行编码。

代码语言:javascript
复制
n := 3 + 4.
m := 2 + 5.
n = m "true".
n == m "true".

另一个有趣的情况发生在类Symbol的实例上

代码语言:javascript
复制
s := #symbol.
t := 'symbol' asSymbol.
s = t "true".
s == t "true!"

之所以会发生这种情况,是因为Symbol类确保了环境中不会存在具有相同底层字符串的两个实例。

票数 3
EN

Stack Overflow用户

发布于 2017-01-17 06:39:53

TL;DR:=:“等于”,==:“相同于”

在Object>>#=中

代码语言:javascript
复制
= 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“原语。回答接收者和参数是否为同一对象(具有相同的对象指针)。请勿在任何其他类中重新定义消息==!Essential。No Lookup。请勿在任何子类中覆盖。请参阅对象文档whatIsAPrimitive。”

代码语言:javascript
复制
<primitive: 110>
self primitiveFailed

因此,您可以覆盖=,但不能覆盖==。

半自动ProtoObject subclass: #Object

#=覆盖的一个示例是

´= aBag“如果(a)两个袋子是同一”种类“的东西,(b)它们具有相同的尺寸。(c)每个元素在它们中出现的次数相同,则两个袋子相等。”

代码语言:javascript
复制
(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”。

代码语言:javascript
复制
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“为接收方回答一个整数散列值,使得--未改变对象的散列值随时间变化不变,--两个相等的对象具有相等的散列值”

代码语言:javascript
复制
| 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为您提供了实现者列表,因此您可以快速找到他们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41684968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档