Scala 定界延续

1.本章要点

  • 延续让你可以回到程序执行当中之前的某个点;

  • 可以在shift块中捕获延续

  • 延续函数一直延展到包含它的reset块的尾部

  • 延续所谓的”余下的运算“,从包含shift的表达式开始,到包含它的reset块的尾部结束,其中shift替换成一个”洞“

  • 当你传入一个参数来调用延续时,这个”洞“将传入的参数值填上

  • 包含shift表达式的代码将被以”延续传递风格“(CPS)重写,直到包含该延续的reset为止

  • 包含shift但没有reset的方法必须加上CPS注解

  • 延续可以用来将对某个树形结构的递归访问变成迭代

  • 延续可以在Web或GUI应用中撤销”控制反转“  

 

2.捕获并执行延续

  延续是一种让你回到程序之前的一个点的一种机制。使用shift结构:

//这里的延续是一个不带参数也不带返回值的函数
执行延续即简单调用cont就跳回shift中那一点
var cont:(Unit=>Unit)=null
...
shift{k:(Unit=>Unit)=>//延续被传递给了shift
cont=k //保存下来,以便以后使用
}
//在Scala中,延续是定界的——只能延续到指定的边界,这个边界由reset{...}标出,调用cont时,执行从shift开始,一直延展到reset块的边界
reset{
...
shift{
k:(Unit=>Unit)=>cont=k
}//对cont的调用将从这儿开始
}//...结束

3.”运算当中挖个洞“

  延续捕获了什么:把shift块想象成一个位于reset块中的洞。当执行延续时,可以将一个值传入到这个洞中,运算继续,就像shift本就是那个值。。。

 

4.reset和shift的控制流传

    双重职责——定义延续职责和捕获延续函数。

    调用reset,代码体开始执行,执行遇到shift,shift的代码体被调用,传入延续参数作为参数,当shift执行完成,执行立即跳转到包含延续的reset末尾。。。    

 

5.reset表达式的值

    如果reset块退出是因为执行了shift,那么得到的值就是shift块的值;如果reset块执行到自己的末尾的话,值就是reset的值(块中最后一个表达式的值);在实际操作,如果reset代码块包含分支或循环,两种情况都可能。    

 

6.reset和shift表达式的类型

    reset和shift都是带有类型参数的方法。

 

7.CPS注解

    某些虚拟机延续的实现方式是抓取运行期栈的快照。当有人调用延续时,运行期栈被恢复成快照的样子(Java虚拟机不允许对栈进行操作)。

    为了在JVM提供延续,Scala对reset块中的代码进行”延续风格“(CPS)的变换。

 

8.将递归访问转化为迭代

    reset和shift方法适合控制流转的模式。每当shift被执行,程序就退出包含它的reset。当被捕获的延续中被调用时,程序又返回shift的位置。。。

 

9.撤销控制反转

 

10.CPS变换

 

11.转换嵌套的控制上下文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员学习圈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值