簡體   English   中英

Scala Continuations - 為什么我的轉移調用不能在try-catch塊內?

[英]Scala Continuations - Why can't my shifted call be inside a try-catch block?

我是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 ,當用戶輸入“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標志)

謝謝@ som-snytt,但你的解決方案與通用解決方案有些差距。 每次使用try-catch塊時,我都不能要求框架用戶編寫def my_check而不是val my_check

但是,我使用了您的解決方案,並構建了以下代碼:

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_protector包裝他的try-catch塊,代碼就會編譯。

不要問我怎么樣或為什么......看起來像編輯VODOU給我...

我沒有在scala 2.10上嘗試過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM