[英]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.