元组赋值在try / catch中不起作用

时间:2018-04-16 16:49:10

标签: scala

我一直试图围绕一个函数执行try/catch,该函数返回一个元组(两个值的两个)。

此版本不起作用:

var a = 0
var b = 0
try {
  (a, b) = my_function(input)
} catch {
  case e: Exception => println("Exception caught: " + e)
}

这个有效:

var a = 0
var b = 0
try {
  val tmp = my_function(input)
  a = tmp._1
  b = tmp._2
} catch {
  case e: Exception => println("Exception caught: " + e)
}

我想强调(a, b) = my_function(input)try/catch声明之外工作。

任何人都可以解释原因吗?

2 个答案:

答案 0 :(得分:3)

避免使用var

我不知道你的例子中my_function是什么,但这里是使用元组的try / catch的模型:

// Tries to turn the input to an Int and return (input.toInt, input.toInt * 2)
def myfunction(input: String): (Int, Int) = {
  (input.toInt, input.toInt * 2)
}

// Will succeed as "4".toInt does not fail
val (a, b): (Int, Int) = try {
  myfunction("4")
} catch {
  case e: NumberFormatException =>
    throw new NumberFormatException(s"Exception caught: $e")
}
// a: Int = 4
// b: Int = 8

// Will throw an exception as "string".toInt is not possible
val (c, d): (Int, Int) = try {
  myfunction("string")
} catch {
  case e: NumberFormatException =>
    throw new NumberFormatException(s"Exception caught: ${e.getMessage}")
}
// java.lang.NumberFormatException: Exception caught: For input string: "string"

修改

Scala确实有自己的Try方法,如下所示:

val (e, f): (Int, Int) = Try {
  myfunction("4")
} match {
  case Success((x, y)) => (x, y)
  case Failure(ex: NumberFormatException) =>
    throw new NumberFormatException(s"Exception caught: ${ex.getMessage}")
  case Failure(ex) =>
    throw new Exception(s"Unexpected exception: ${ex.getMessage}")
}
// e: Int = 4
// f: Int = 8

val (g, h): (Int, Int) = Try {
  myfunction("string")
} match {
  case Success((x, y)) => (x, y)
  case Failure(ex: NumberFormatException) =>
    throw new NumberFormatException(s"Exception caught: ${ex.getMessage}")
  case Failure(ex) =>
    throw new Exception(s"Unexpected exception: ${ex.getMessage}")
}
// java.lang.NumberFormatException: Exception caught: For input string: "string"

答案 1 :(得分:1)

  

我想强调的是(a,b)= my_function(输入)在try / catch语句之外工作。

它没有。如果你在没有try

的情况下做同样的事情
var a = 0
var b = 0
(a, b) = my_function(input)

你会发现它不起作用,所以try并不相关。你叫什么"元组分配"是模式匹配的一个特例,它只能用于引入 new valvar s,而不是分配给现有的。

但是因为try/catch是一个表达式,你可以做

val (a, b) = try {
  my_function(input)
} catch {
  case e: Exception => 
    println("Exception caught: " + e)
    (0, 0)
}

请注意,try/catch的类型是trycatch部分的常见超类型。