簡體   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