10.3.2 利用连续的代码
来源:互联网 发布:淘宝评价管理网址 编辑:程序博客网 时间:2024/05/12 22:50
10.3.2 利用连续的代码
问题是,我们既希望做尾递归调用,还要在尾递归调用完成后,再执行一些代码。这看起来是一个棘手的问题,但有一个有趣的解决方案。我们把要在递归调用完成后执行的所有代码,拿来作为参数值,提供给递归调用,这样,我们要写的函数将仅只包含一个递归调用。
可以把这个看作是另一种类型的累加器参数:我们不是累加值,而是累加“需要在以后运行的代码”。现在的问题是,我们如何能拿到其余的代码,并把它作为给函数的参数值?这可能要感谢一等函数(first class functions),这个最后的参数就称为连续(continuation),因为它指定运行应该如何继续。
在看过一些实际的例子后,这一切会变得更清楚。清单 10.17 是一个简单的函数,首先,以通常的风格实现,然后,使用连续。这里,我们将使用 C#,只有一个新的概念要理解,但请记住,C# 不支持尾递归:在 C# 中,这个技术不能作为递归的优化而使用。(在 C# 中连续仍然可用,只是不是为递归的。)
清单 10.17 用连续写代码(C#)
// Reports result as return value
int StringLength(string s) {
returns.Length;
}
void AddLengths() { [1]
int x1= StringLength("One");
int x2= StringLength("Two");
Console.WriteLine(x1+ x2);
}
// Reports result using continuations
void StringLengthCont(string s,Action<int> cont) {
cont(s.Length); [2]
}
void AddLengthsCont() {
StringLengthCont("One", x1 => [3]
StringLengthCont("Two", x2 => [4]
Console.WriteLine(x1 + x2)
));
}
在两个版本中,我们首先声明了计算字符串长度的函数。按通常的编程风格,把结果作为返回值;当使用连续时,我们增加了一个函数(连续)作为最后一个参数值。要返回结果,StringLengthCont 函数调用这个连续[2]。我们将使用函数代替通常的 return 语句,这样,值是作为给函数的参数值 ,而不是把它作为结果存储在栈中。
下一个函数,AddLengths,[1]计算两个字符串的长度,再把这两个值加起来,再输出结果。在使用连续的版本中,只包括一个顶层对StringLengthCont 函数的调用[3]。调用的第一个参数值是字符串,第二个参数值是连续。顶层的调用是函数要做的最后事情,因此,在 F# 中,可以使用尾调用运行,它不会占用任何栈空间。
连续接收第一个字符串的长度作为参数值;在内部,再为第二个字符串调用StringLengthCont。另外,把连续作为最后参数值给它,它只被调用一次,我们可以计算两个长度的和,并输出结果。在 F# 中,在连续内部的调用[4]还是尾调用,因为它是代码在 lambda 函数中所要做的最后工作。现在,我们要看一下使用这种编程风格,来优化我们以前的函数,计算树中元素的和。
- 10.3.2 利用连续的代码
- 利用连续点灯定位汇编代码的错误
- 连续滚动的广告代码
- 文字连续滚动的公告代码
- 连续邮资问题的实现代码
- 上下左右连续滚动图片的JS代码
- 上下左右连续滚动图片的JS代码
- 上下左右连续滚动图片的JS代码
- 按键支持连续按的相应代码
- 利用基因算法训练连续隐马尔柯夫模型的语音识别
- 利用monkeyrunner给Android屏幕连续截图的小程序
- 利用monkeyrunner给Android屏幕连续截图的小程序
- 利用OpenCV将连续的图片写入视频
- 连续2个事务代码BDC录拼锁住的问题
- MGF病毒的利用代码
- 测试矩阵连续运算的速度问题的代码
- 查找连续的数据2
- 连续滚动代码
- 混实验室这一年
- iptables
- php5-dev
- Linux 下Sqlite3 的安装及应用
- IOS中ViewController中的loadView方法使用注意
- 10.3.2 利用连续的代码
- linux 管道传递socket套接字
- 生产者和消费者的多线程问题
- 程序设计基石与实践之数据成员与set和get函数
- 你用icloud网页关闭激活锁功能
- 关于ajax跨服务器读取数据的验证
- 数据结构基础(5) --归并排序
- java黑马基础题
- Web前端开发与iOS终端开发的异同