[英]Comparing Blocks in Squeak Smalltalk
我正在編程吱吱聲,需要比較兩個代碼塊,如下所示:(toRunBlock是一個實例變量)
~~~Other code~~~
toRunBlock := [nil].
~~~Other code~~~
但在某些時候,我需要將它與另一個代碼塊進行比較:
(toRunBlock = [nil]) ifTrue: [
"Run some code if toRunBlock hasn't been overwritten"
].
但是這個檢查總是假的,我找不到辦法檢查它們是否相等。 有人可以幫我解決這個問題嗎?
正如@LeandroCaniglia指出的那樣,你不應該比較塊。 以下是兩種在不比較塊的情況下解決問題的方法:
將變量初始化為nil
。 在您的訪問器方法中,您可以懶惰地初始化它:
toRunBlock ^ toRunBlock ifNil: [ [] ]
現在,當您查看變量toRunBlock
,除非已發送#toRunBlock
或通過其他方式設置了塊,否則#toRunBlock
nil
。
您的代碼將變為:
toRunBlock ifNil: [ "Run some code if toRunBlock hasn't been overwritten" ].
通過設置可以檢查的實例變量來使用其他狀態。 這可能是你的setter方法,例如:
toRunBlock: aBlock toRunBlock := aBlock. hasToRunBlockBeenSet := true
要檢查你可以使用這樣的方法:
hasToRunBlockBeenSet ^ hasToRunBlockBeenSet ifNil: [ false ]
您的代碼將變為:
self hasToRunBlockBeenSet ifTrue: [ "Run some code if toRunBlock hasn't been overwritten" ].
第二種方法可以說更可靠。
除了引用相等性之外,BlockClosures沒有定義平等。 雖然兩個塊可能表現相同,但它們仍然不同,因為它們是閉包而不僅僅是代碼片段。 每個塊都引用了創建它的上下文(方法激活或其他塊),因此在這方面你的兩個[nil]
至少會有所不同。
您只能通過存儲其他地方之前的內容來檢查該塊是否仍然與之前相同 。 假設[nil]
是您的情況下的某種默認值,您可以將該[nil]
塊存儲在另一個實例變量或類池變量(例如,defaultRunBlock)中,並與該變量比較toRunBlock(通過引用)以檢查是否toRunBlock已被更改。
Object subclass: #YourClass
instanceVariableNames: 'toRunBlock defaultRunBlock'
"or as class variable:"
classVariableNames: 'DefaultRunBlock'
poolDictionaries: ''
category: 'Kernel-Methods'
initialize
defaultRunBlock := [nil]
otherCode
toRunBlock := defaultRunBlock
whereYouCompareThem
toRunBlock == defaultRunBlock ifTrue: [ "..." ]
或者,如果您想檢查自上次調用后一個方法后是否更改了toRunBlock,您也可以將之前的值存儲在另一個實例變量中。
whereYouCompareThem
toRunBlock == previousRunBlock ifTrue: [ "..." ].
previousRunBlock := toRunBlock
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.