我不同意,reset 中的代码没有shift 就死了。实际上 reset 只是定义了延续的边界(那是因为它们被称为 delimited 延续)。如果你在 reset 中的某个地方有 shift 并且你不调用延续,那么代码就会死掉功能。例如:
reset {
println(1)
shift((k: Unit => Unit) => println(2))
println(3)
}
shift 后面的代码已经死掉了(println(3)),因为我还没有调用k(Unit)。
另一方面,reset 似乎期望从它的主体中获得一些特殊的返回类型 - 使用 @cpsParam 注释进行注释的返回类型。你可以查看reset方法的定义:
def reset[A,C](ctx: => (A @cpsParam[A,C])): C = ...
而shift 产生的正是reset 方法所期望的。这是shift方法的定义:
def shift[A,B,C](fun: (A => B) => C): A @cpsParam[B,C] = ...
但您仍然可以使用 reset 而无需在其中调用 shift。这个技巧可以做到:
def foo[T](body: => T @cps[Any]) = reset(body)
foo {
println("it works")
}
请注意,@cps 只是 @cpsParam 的类型别名。这是定义:
type cps[A] = cpsParam[A, A]