无法在 GNU Smalltalk 中调用 "function"
Can not call "function" in GNU Smalltalk
我想定义block并这样调用:
add := [ :a :b |
^(a+b).
].
n := add value: 1 value: 2.
但是当我尝试的时候,我得到一个错误:
$ gst 3.1.st
Object: 3 error: return from a dead method context
SystemExceptions.BadReturn(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.BadReturn class(Exception class)>>signal (ExcHandling.st:151)
SmallInteger(Object)>>badReturnError (Object.st:1389)
UndefinedObject>>executeStatements (3.1.st:3)
如何在 GNU Smalltalk 中调用函数?
好吧,我删除了 return 语句,这段代码工作正常。但是当我尝试定义更复杂的函数时,例如:
nod := [ :a :b |
(a=b) ifTrue: [a].
(a>b) ifTrue: [nod value: (a-b) value: b].
(a<b) ifTrue: [nod value: a value: (b-a)].
].
n := nod value: 1 value: 2.
n printNl.
它打印 nil。如果我用 "early exit":
定义
nod := [ :a :b |
(a=b) ifTrue: [^a].
(a>b) ifTrue: [nod value: (a-b) value: b].
(a<b) ifTrue: [nod value: a value: (b-a)].
].
n := nod value: 1 value: 2.
n printNl.
它给了我同样的错误:return from a dead method context。
我是这样解决这个问题的:
nod := [ :a :b |
(a=b) ifTrue: [
a
] ifFalse: [
(a>b) ifTrue: [nod value: (a-b) value: b] ifFalse: [nod value: a value: (b-a)].
]
].
n := nod value: 1 value: 2.
n printNl.
但我认为,这不是很美的方式。
删除块内的非本地 return (^)、括号和句点。然后再试一次。
从您的代码中删除 return 语句 (^
),它将正常工作。
在smalltalk中,returning退出出现return语句的方法。它用于提前退出,例如 a < b ifTrue: [^a] ifFalse:[^b]
.
在这种情况下,您不希望该块退出包含方法,您只希望它在发送时计算出某些东西 value:value:
。一个块的计算结果是其中的最后一条语句,因此只需将其设为常规语句即可。
顺便说一下,您收到的错误消息也解释了问题:您正试图从一个已经失效的方法中 return 3
。
您已经接受了原始问题的答案,然后重新定义了您的问题。
要回答您更新后的问题,您可以使用块 returns 其最后一条语句的值这一事实,并使用局部变量:
nod := [ :a :b | |r|
(a = b) ifTrue: [r := a].
(a > b) ifTrue: [r := nod value: (a-b) value: b].
(a < b) ifTrue: [r := nod value: a value: (b-a)].
r
].
不过,我对上下文很好奇。我怀疑将 class 定义为 selector/method 可能更合适。
顺便说一句,如果任一参数为负,上述实现将进入无限递归。
获得所需结果的最简单方法是:
nod := [ :a :b | a gcd: b ].
:)
我想定义block并这样调用:
add := [ :a :b |
^(a+b).
].
n := add value: 1 value: 2.
但是当我尝试的时候,我得到一个错误:
$ gst 3.1.st
Object: 3 error: return from a dead method context
SystemExceptions.BadReturn(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.BadReturn class(Exception class)>>signal (ExcHandling.st:151)
SmallInteger(Object)>>badReturnError (Object.st:1389)
UndefinedObject>>executeStatements (3.1.st:3)
如何在 GNU Smalltalk 中调用函数?
好吧,我删除了 return 语句,这段代码工作正常。但是当我尝试定义更复杂的函数时,例如:
nod := [ :a :b |
(a=b) ifTrue: [a].
(a>b) ifTrue: [nod value: (a-b) value: b].
(a<b) ifTrue: [nod value: a value: (b-a)].
].
n := nod value: 1 value: 2.
n printNl.
它打印 nil。如果我用 "early exit":
定义nod := [ :a :b |
(a=b) ifTrue: [^a].
(a>b) ifTrue: [nod value: (a-b) value: b].
(a<b) ifTrue: [nod value: a value: (b-a)].
].
n := nod value: 1 value: 2.
n printNl.
它给了我同样的错误:return from a dead method context。
我是这样解决这个问题的:
nod := [ :a :b |
(a=b) ifTrue: [
a
] ifFalse: [
(a>b) ifTrue: [nod value: (a-b) value: b] ifFalse: [nod value: a value: (b-a)].
]
].
n := nod value: 1 value: 2.
n printNl.
但我认为,这不是很美的方式。
删除块内的非本地 return (^)、括号和句点。然后再试一次。
从您的代码中删除 return 语句 (^
),它将正常工作。
在smalltalk中,returning退出出现return语句的方法。它用于提前退出,例如 a < b ifTrue: [^a] ifFalse:[^b]
.
在这种情况下,您不希望该块退出包含方法,您只希望它在发送时计算出某些东西 value:value:
。一个块的计算结果是其中的最后一条语句,因此只需将其设为常规语句即可。
顺便说一下,您收到的错误消息也解释了问题:您正试图从一个已经失效的方法中 return 3
。
您已经接受了原始问题的答案,然后重新定义了您的问题。
要回答您更新后的问题,您可以使用块 returns 其最后一条语句的值这一事实,并使用局部变量:
nod := [ :a :b | |r|
(a = b) ifTrue: [r := a].
(a > b) ifTrue: [r := nod value: (a-b) value: b].
(a < b) ifTrue: [r := nod value: a value: (b-a)].
r
].
不过,我对上下文很好奇。我怀疑将 class 定义为 selector/method 可能更合适。
顺便说一句,如果任一参数为负,上述实现将进入无限递归。
获得所需结果的最简单方法是:
nod := [ :a :b | a gcd: b ].
:)