2013-07-15 31 views
2

Scala 2.10.2。运行Scala中移位的异常

import util.continuations._ 
import concurrent.ops._ 

object Main { 
    def main(args: Array[String]) { 
     reset { 
      try { 
       shift { cont: (Unit => Unit) => { 
        spawn { 
         throw new Exception("blah") 
         cont() 
        } 
       }} 
       println("after shift") 
      } catch { 
       case e: Exception => println(e) 
      } 
      println("reset end") 
     } 
    } 
} 

给人

Cont.scala:16: error: type mismatch; 
found : Unit 
required: Unit @scala.util.continuations.cpsParam[Unit,Unit] 
       case e: Exception => println(e) 
              ^
one error found 

如果删除了try/catch块一切都很好。我仍然试图弄清楚Scala中的延续如何工作,但是这个完全避开了我。

回答

1

只是说明明显 - 这是一个斯卡拉类型推断符合cps-annotation问题。 catch块不包含任何cps注释表达式。在这种情况下,捕捉块预计将同一类型的试块的:

Unit @cps[Unit] // same as Unit @cpsParam[Unit,Unit] 

我的经验,类型推测和斯卡拉CPS-转变并不总是按照预期工作,在一个版本的Scala中工作的东西在另一个版本中不起作用。

存在着解决办法,如Scala Continuations - Why can't my shifted call be inside a try-catch block?

不知道是否可以帮助你的情况(即斯卡拉版本2.10.2)中提到的try_protector

0

您是否打算用try/catch语句来捕获Exception("blah")

即使编译了,spawn已被弃用也会在另一个线程上运行延续之前发生。

没有的try/catch你有这样的事情:

println("in main " + Thread.currentThread()) 
reset { 
    shift { cont: (Unit => Unit) => 
    { 
     spawn { 
     println("in spawned " + Thread.currentThread()) 
     cont() 
     } 
    } 
    } 
    println("after shift " + Thread.currentThread()) 
    println("reset end") 
} 

}

cont功能是对应于这个函数的代码的物化部分:

val cont =() => { 
    println("after shift " + Thread.currentThread()) 
    println("reset end") 
} 

So当您执行spawn { cont() }时,您只需在新的单独线程中运行两个println。运行该程序,我得到:

in main Thread[main,5,main] 
in spawned Thread[Thread-1,5,main] 
after shift Thread[Thread-1,5,main] 
reset end 

这表明继续运行在单独的线程上。现在,如果你在cont()之前插入throw new Exception(),那么你所得到的只是在产生的线程上抛出的异常(显然该异常将被吞下)。

在你试图做什么之后,会在try/catch内部运行延续并抛出异常吗?

reset { 
    shift { cont: (Unit => Unit) => 
    spawn { 
     println("in spawned " + Thread.currentThread()) 
     try { cont() } 
     catch { case e: Exception => println(e) } 
    } 
    } 
    println("after shift " + Thread.currentThread()) 
    throw new Exception("blah") 
    println("reset end") 
} 

}

此打印:

in main Thread[main,5,main] 
in spawned Thread[Thread-1,5,main] 
after shift Thread[Thread-1,5,main] 
java.lang.Exception: blah