0

我今天刚开始使用applescript,听说过子程序。所以我决定编写一个小测试程序,它接受一个数字,将其加 9,减 27,除以 3,然后返回结果。只有它不返回结果;它会返回一个StackOverFlow错误。什么是 StackOverFlow 错误?

程序编译正确,不知道哪里出了问题。就像我说的,我对 AppleScript很陌生。这是我正在运行的代码:

calculate_result(text returned of (display dialog "Enter a number:" default answer ""))

on calculate_result(this_result)
    set this_result to this_result + 9
    set this_result to this_result - 27
    set this_result to this_result / 3
    return calculate_result(this_result)
end calculate_result
4

3 回答 3

3

摘自类似问题的答案...

参数和局部变量在堆栈上分配(对象存在于堆上的引用类型和引用该对象的变量)。堆栈通常位于地址空间的上端,当它用完时,它会朝向地址空间的底部(即朝向零)。

您的进程也有一个堆,它位于进程的底部。当你分配内存时,这个堆会增长到地址空间的上端。如您所见,堆有可能与堆栈“碰撞”(有点像技术板!!!)。

堆栈溢出错误意味着堆栈(您的子例程)溢出(自身执行了很多次以至于崩溃)。堆栈溢出错误通常是由错误的递归调用引起的(在 AppleScript 的情况下,是错误的子例程调用)。

通常,如果您的子例程返回值,请确保该值不是子例程名称。否则堆栈将溢出,导致程序崩溃(如果 return 语句不在try块内)。只需更改此:

return calculate_result(this_result)

……到这个

return this_result

...你应该很高兴去!

在某些情况下,可以返回子程序名称,但前提是存在终止条件。例如,如果用户输入了无效数字,子程序可以重新运行自身,但前提数字无效(如下所示):

on get_input()
    set this_number to null
    try
        set this_number to the text returned of (display dialog "Please enter a number:" default answer "") as number
    on error --the user didn't enter a number and the program tried to coerce the result into a number and threw an error, so the program branches here
        return get_input()
    end try
    return this_number
end get_input

在上述情况下,终止条件发生在用户输入实际号码时。您通常可以判断程序何时会抛出 Stack Overflow 错误,因为没有终止条件。

我希望这个信息帮助!

于 2011-08-12T22:02:01.513 回答
2
return calculate_result(this_result)

您正在递归调用再次传递this_result给它的子例程,并且被调用的函数依次调用子例程等等。变量,函数的返回地址等,驻留在堆栈上。由于子例程的递归性质,堆栈溢出。

于 2011-08-12T22:00:55.350 回答
2

在“calculate_result”中,最后一行再次调用“calculate_result”。将行更改为:

return (this_result)

子程序的最后一行只是再次调用子程序,它再次调用子程序,再次调用子程序,再次调用子程序,再次调用子程序......

我想你明白了——AppleScript,正如你所写的那样——崩溃,因为它只是不断地调用自己,并最终耗尽内存,从而触发堆栈溢出错误。

每当程序耗尽某种内存空间时,就会发生堆栈溢出错误——它不特定于 AppleScript——它可以在任何编程语言中发生。有关堆栈溢出错误的更深入解释,请参阅此答案:

什么是堆栈溢出?

于 2011-08-12T22:01:07.667 回答