我对这段代码感到困惑:
| a b c| a := 1. b := [a := a + 1]. c := [a := a - 2. b].
10 timesRepeat: (a even ifTrue: b ifFalse: c). a我的假设是,这段代码将a设置为-19。每次迭代将测试a是否为偶数,但a将是奇数,因此将调用c,在不影响其奇偶性的情况下从a减去2。c不会调用b,因为如果我对块的理解是正确的,则返回块的最后一个元素而不是求值;因此c将返回b,但是timesRepeat丢弃任何返回的内容,因此c中的b没有任何效果。
我的假设被证明是错误的:这段代码将a设置为9。为了了解发生了什么,我稍微修改了这段代码:
| a b c| a := 1. b := [Transcript show: (a displayString). a := a + 1]. c := [Transcript show: (a displayString). a := a - 2. b.].
10 timesRepeat: (a even ifTrue: b ifFalse: c). a这就是要打印的东西:
1-1012345678那么,b 到底叫还是?我的假设是b被返回而不是被调用,这是错误的吗?
让我们试着检查一下:
jkl := [Transcript show: 'I am called too.'].
asdf := [Transcript show: 'I am called!'. jkl].
10 timesRepeat: asdf不,asdf没有在这里调用jkl:
I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!I am called!不管怎么说,如果c总是调用b,那么它的效果将是有效地从a中减去1;但这是不可能的。相反,第一次迭代似乎调用了c,然后神秘地,每次迭代似乎都调用了b,即使a是奇怪的!
这里发生了什么事??
发布于 2019-06-15 23:49:35
timesRepeat:选择器需要一个块作为参数。您使用括号内的表达式调用它:
10 timesRepeat: (a even ifTrue: b ifFalse: c).然而,正是这样,c被定义为块[a := a - 2. b],它返回b的值,正好是一个块。因此,timesRepeat:很高兴,它在每次迭代( a是奇数)上执行块b。如果您正确地将它写成:
10 timesRepeat: [a even ifTrue: b ifFalse: c].最后,a将达到预期的-19。
关于您的声明:如果我对块的理解是正确的,则返回块的最后一个元素而不是求值,但情况并非如此。对于块中的最后一条语句,除了它的结果实际上在执行该块时返回该块的值外,没有任何特殊处理。块中的最后一条语句只是变量的名称。变量的值恰好是一个块,但是不管它是什么,在Smalltalk中只有一个变量名作为语句返回变量的值。如果变量恰好是块,则得到块。没有执行块。
考虑以下几个方面:
[a := 1. b := 2. c := a+b]执行此块时,a的值为1,b为值2,c为值3,块返回的值为c的值,即3。
[a := 1. b := 2. a]如果执行此块,结果将是a的值,即1。
[a := 1. b := 2. c := [a+b]. c]如果执行此块,结果将是变量c表示的块。它不执行块c。这与前面的例子是一致的。
因此,当您执行块[Transcript show: 'I am called!'. jkl].时,不执行末端的jkl。它的价值刚刚还回来。如果您想要执行它,您可以编写asdf := [Transcript show: 'I am called!'. jkl value]. --在发送value消息时将执行一个块。执行块[Transcript show: 'I am called!'. jkl value].的结果将是执行块jkl的结果。
发布于 2019-06-17 02:11:24
也许只有我一个人,但我觉得下面的第二句话有点模糊:
然而,正是这样,c被定义为块a := a-2.b,它返回b的值,而这恰好是块。因此,timesRepeat:是愉快的,它在每个迭代中执行块b,其中a是奇数的。
Smalltalk的语义是:
这个顺序是至关重要的,因为评估可能有副作用。
所以,实际发生的是:
10计算为10a even ifTrue: b ifFalse: c的计算结果为b。副作用a = -1。10 timesRepeat: b或10 timesRepeat: [a := a + 1]因此,a = 9。
https://stackoverflow.com/questions/56614528
复制相似问题