2012-01-13 84 views
8

通常情況下,我希望將變量作用於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 

是什麼像在斯卡拉這可能嗎?有沒有體面的解決方法?如果不是,還有哪些其他語言支持這樣的想法?

回答

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 S的都不是可用的外面。

+0

非常酷!謝謝! – vertexshader 2012-01-13 03:42:31

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值。

+0

+1好主意...... – Landei 2012-01-13 12:36:06

0

你可以爲它創建一個範圍...

{ 
    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 
}