Smalltalk:最好避免非本地returns?算法重写

Smalltalk : best to avoid non-local returns? Algorithm rewrite

此方法(来自 SOM 基准测试)依赖于 Smalltalk 非本地 returns。有没有办法在没有它们的情况下产生相同的结果?

placeQueenNonLocalReturn: c
    1 to: 8 do: [ :r | 
        (self row: r column: c)
            ifTrue: [
                queenRows at: r put: c.
                self row: r column: c put: false.
                (c = 8) ifTrue: [ ^true ].
                (self placeQueen: c + 1) ifTrue: [ ^true ].
                self row: r column: c put: true ] ].
    ^false
!

注意(另一个相关问题):是否可以在不了解调用者和被调用者的情况下更改此代码?我想它应该可以更好地理解目的,但对于我的问题,该方法不应该是独立的吗?

是的,这是可能的。 您使用非本地 return 只是为了快速退出 1 to: 8 do: 循环。 您可以使用其他语法轻松编写循环,例如:

exit := false.
row := 1.
[row < 9 andNot: [exit]] whileTrue: [ (self row: r column: c)
            ifTrue: [
                queenRows at: r put: c.
                self row: r column: c put: false.
                c = 8 ifTrue: [ exit := true ] 
                      ifFalse: [ (self placeQueen: c + 1) 
                                    ifTrue: [ exit := true ] 
                                    ifFalse: [self row: r column: c put: true ] ] ].
^exit

注意循环中调用placeQueen:好像是递归的,可能是你方法的selector不对

我不明白 "knowing about callers and callees" 是什么意思...我对代码进行了大部分语法重写。 自我控制也一样。 这个方法不是独立的,它似乎是8 Queen问题解决方案的一部分,但是依赖于(self row: r column: c)来检查一个新queen的位置的有效性。

纠正一个误会。显示的代码 包含任何非本地 return,因此它不能依赖此功能。

显示的 returns 都是正常的 returns - 它们 return 返回给调用者的结果。 非本地 return 是指值被 returned 到调用方法以外的其他地方的情况。

所以没有理由避免显示 returns,