if语句作用域变量

时间:2012-01-13 03:06:40

标签: scala

我经常希望创建作用于if语句的变量。有些计算只涉及特定的“if”语句 - 用临时变量污染外部范围会产生异味。

我想做什么:

val data = (whatever)

if (val x = data*2+5.4345/2.45; val y = data/128.4; x*y < 10) 
  x * y
else
  x * 2

println(x) //ERROR!

另一种选择是相当混乱:

val data = (whatever)

if (data*2+5.4345/2.45*data/128.4 < 10) 
  data*2+5.4345/2.45*data/128.4
else
  data*2+5.4345/2.45 * 2

我试图避免的明显替代方案:

val data = (whatever)
val x = data*2+5.4345/2.45
val y = data/128.4

if (x*y < 10) 
  x*y
else
  x * 2

println(x) //OK

在Scala中是否可以这样?有一个体面的解决方法吗?如果没有,其他哪些语言支持这样的想法?

3 个答案:

答案 0 :(得分:20)

由于Scala中的if是一个表达式,即它返回一个值,通常您可以为if表达式的结果设置一些值。所以你的第三种选择就好了:把它放在一个代码块中,即

val data = (whatever)
val myValue = {
  val x = data*2+5.4345/2.45
  val y = data/128.4

  if (x*y < 10) 
    x*y
  else
    x * 2
}

块内声明的val在其外部都不可用。

答案 1 :(得分:5)

您可以使用模式匹配:

val data = 123

val (result, x) = (data*2+5.4345/2.45, data/128.4) match {
  case (x, y) if x * y < 10 => (x * y, x)
  case (x, _)               => (x * 2, x)
}

println(x)

result包含x * yx * 2的结果,具体取决于运行的计算,x根据需要包含data*2+5.4345/2.45的值。

答案 2 :(得分:1)

你可以为它创建一个范围......

{
  val x = data*2+5.4345/2.45
  val y = data/128.4;
  if ( x*y < 10) 
    x * y
  else
    x * 2
}

或者,为了更清楚,

locally {
  val x = data*2+5.4345/2.45
  val y = data/128.4;
  if ( x*y < 10) 
    x * y
  else
    x * 2
}