我是 Scala 延续的新手,对 scala 语言一般来说相对较新。
我尝试使用 Scala continuation 并编写了以下代码:
case class MyException(msg:String) extends Exception
def go:Int = reset {
println("enter your input")
val my_check = //try
{
val user_input = readLine()
if (!user_input.matches("\\w+")) {
throw new MyException("illegal string: " + user_input)
}
shift {
k: (Boolean => Int) => {
if (user_input == "true") {
k(true)
}
else if (user_input == "false") {
k(false)
}
else {
// don't even continue
0
}
}
}
}
// catch {
// case MyException(msg) => false
// }
if (my_check) {
println("TRUE")
1
}
else {
println("FALSE")
-1
}
}
println(go)
代码按预期工作:当用户输入非字母数字字符串MyException
时,抛出 a,当用户输入“true”时,代码继续my_check = true
,当用户输入“false”时,代码继续my_check = false
,当用户输入字母数字时不是“true”或“false”的字符串,go
函数以 0 退出。
然后我尝试将一些代码包装在 try-catch 块中(注释所在的位置),编译失败:
错误:在非 cps 位置找到 cps 表达式
val my_check = 尝试
我知道将异常“注入”到延续中存在问题,但是为什么我不能简单地将转移的调用放在 try-catch 块中?
我在我计划的框架中需要这个,程序员不会意识到他的代码是以延续形式使用的(他会调用一些他认为是“正常”的函数,但实际上会执行shift
)。
显然,我需要他能够在 try-catch 块中调用该函数,即使转移调用本身不会引发异常。
这个问题可以用ControlContext解决吗?如果我在值上添加一些“打字”规则(可能使用@cps[..])会有帮助吗?
我已经考虑过使用 Actors 的替代方案,因此您不会因此获得任何功劳:)
谢谢,
(PS 我使用的是 Scala 2.9.2,显然使用了-P:continuations:enable标志)