在Pharo Smalltalk中,=和==有什么不同?它们的名称是什么,一个isEqual和另一个?
= ~= equality / inequality (deep)
== ~~ equality / inequality (shallow)发布于 2017-01-17 06:07:04
是的,==是identity,它使用一个原语来比较指针是否指向相同的地址(即相同的对象)。
=是相等的,这意味着两个对象是相等的,尽管它们可能是两个不同的对象。默认情况下,=使用==,但它可以重新实现。另外,当您重新实现=时,建议您也重新实现hash,这样散列集合就不会变得疯狂
发布于 2017-01-17 09:44:20
需要考虑的一件重要事情是,=不仅在代码比较两个对象时显式使用。消息=还被许多其他消息隐含地使用,例如:includes:、<=、>=、remove:、keyAtValue:、indexOf:、upTo:、peekFor:、D10、D11(在D12中)、D13(以及朋友D14、D15等)和许多其他消息。
这意味着当您在类中重新定义=时,应该确保
=实现是健壮的(例如,banana = car不会产生错误)和=时,您也会重新定义e.g.第一种情况的原因是能够比较任何两个对象,而发送者在发送=消息之前不必特别注意。
第二个原因是如果将来在散列集合(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。
当阅读a == b时,Smalltalkers会说a和b是同一个对象,或者a等同于b,甚至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也是==,因为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类确保了环境中不会存在具有相同底层字符串的两个实例。
发布于 2017-01-17 06:39:53
TL;DR:=:“等于”,==:“相同于”
在Object>>#=中
= 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。”
<primitive: 110>
self primitiveFailed因此,您可以覆盖=,但不能覆盖==。
半自动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有股臭味,追踪这些电话会很有趣。”
有关更基本的对象,请参阅以下内容:

祝你探索愉快。
在Spotter中,hash #im或= #im为您提供了实现者列表,因此您可以快速找到他们。

https://stackoverflow.com/questions/41684968
复制相似问题