Scala延续-为什么可以';我的电话不是在试接区内吗?

Scala延续-为什么可以';我的电话不是在试接区内吗?,scala,exception-handling,try-catch,continuations,try-catch-finally,Scala,Exception Handling,Try Catch,Continuations,Try Catch Finally,我不熟悉Scala continuations,一般来说对Scala语言也比较陌生 我尝试使用Scala continuations并编写了以下代码: case class MyException(msg:String) extends Exception def go:Int = reset { println("enter your input") val my_check = //try { val user_input = readLine() if (!

我不熟悉Scala continuations,一般来说对Scala语言也比较陌生

我尝试使用Scala continuations并编写了以下代码:

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)
import scala.util.continuations._

case class MyException(msg:String) extends Exception

object try_protector {
  def apply[A,B](comp: => A @cps[B]):A @cps[B] = {
    comp
  }
}

object Test extends App {
  def go: Int = reset {
    println("enter your input")
    val my_check = try_protector { 
      try {
        val user_input = readLine()
        if (!user_input.matches("\\w+")) {
          throw new MyException("illegal string: " + user_input)
        }
        shift {
          k: (Boolean => Int) => {
            user_input match {
              case "true"   => k(true)
              case "false"  => k(false)
              case _        => 0
            }
          }
        }
      } catch {
        case MyException(msg) => false
      }
    }

    if (my_check) {
      println("TRUE")
      1
    } else {
      println("FALSE")
      -1
    }
  }
  println(go)
}
代码按预期工作:当用户输入一个非字母数字字符串时,抛出一个
MyException
,当用户输入“true”时,代码继续执行
my_check=true
,当用户输入“false”时,代码继续执行
my_check=false
,当用户输入一个非“true”的字母数字字符串时也不是“false”
go
函数以0退出

然后,我尝试将一些代码包装到一个try-catch块(注释所在的位置)中,但编译失败,原因是:

错误:在非cps位置找到cps表达式

val my_check=试试看

我知道将异常“注入”到延续中会有问题,但为什么我不能简单地将移位调用放在try-catch块中呢

在我计划的框架中,我需要这个,在这个框架中,程序员不会意识到他的代码是以延续形式使用的(他会调用一些他认为“正常”的函数,但实际上会执行
移位

显然,我需要他能够在try-catch块内调用函数,即使移位调用本身不会引发异常

这个问题可以用什么方法解决? 如果我在值上添加一些“键入”规则(可能是@cps[…]),会有帮助吗

我已经考虑过使用演员的替代方案,所以你不会因此获得任何荣誉:)

谢谢


(顺便说一句,我使用的是Scala 2.9.2,显然使用了-p:continuations:enable标志)

谢谢@som snytt,但您的解决方案与通用解决方案有点相去甚远。我不能要求框架用户每次使用try-catch块时都编写
def my_-check
,而不是
val my_-check

但是,我使用了您的解决方案,并构建了以下代码:

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)
import scala.util.continuations._

case class MyException(msg:String) extends Exception

object try_protector {
  def apply[A,B](comp: => A @cps[B]):A @cps[B] = {
    comp
  }
}

object Test extends App {
  def go: Int = reset {
    println("enter your input")
    val my_check = try_protector { 
      try {
        val user_input = readLine()
        if (!user_input.matches("\\w+")) {
          throw new MyException("illegal string: " + user_input)
        }
        shift {
          k: (Boolean => Int) => {
            user_input match {
              case "true"   => k(true)
              case "false"  => k(false)
              case _        => 0
            }
          }
        }
      } catch {
        case MyException(msg) => false
      }
    }

    if (my_check) {
      println("TRUE")
      1
    } else {
      println("FALSE")
      -1
    }
  }
  println(go)
}
而且它有效!(在scala 2.9.2上)

用户只需用
try\u protector
包装他的try-catch块,代码就会编译

不要问我怎么做或者为什么。。。在我看来,这就像是你


我还没有在scala 2.10上尝试过它。

我们将为找到解决方案而给予奖励,而不仅仅是为了解释为什么不能这样做……我尝试过定义一些“ctry”“ccatch”,我的框架的用户将使用它,而不是标准的“try”和“catch”,但我真的感到困惑。这样的解决方案也将算作赏金:)