![](/img/trans.png)
[英]What is the difference between classVariableNames: '' and instanceVariableNames: '' when setting up a Singleton in 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:
等的朋友),等等。
這意味着當您在類中重新定義=
,應確保
=
實現是可靠的(例如, banana = car
沒有錯誤)並且 =
您還重新定義了hash
。 第一個條件的原因是能夠比較任何兩個對象,而發送方在發送=
消息之前不必特別注意。
第二個原因是,如果將來將您的對象用於哈希集合( 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
是相同的 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
也是==
因為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時有些氣味,跟蹤這些呼叫很有趣。
有關更多基本對象,請參見以下內容:
祝您探索愉快。
在hash #im
, hash #im
或= #im
為您提供了實施者列表,因此您可以快速找到它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.