2011-06-01 59 views
3

想了解我的第一個Scala應用程序中的某些錯誤後,我發現我的限制函數並不完全正常工作......完全沒有!如何在Scala中編寫限制函數?

因此,這裏是我的第一次嘗試

def limit(x : Double, min: Double, max : Double) = { 
    if (x < min) min; 
    if (x > max) max; 
    x; 
    } 

它總是返回x

第二次嘗試是這樣的:

def limit(x : Double, min: Double, max : Double) : Double = { 
    if (x < min) return min; 
    if (x > max) return max; 
    x; 
    } 

和它的工作。

所以我的問題:爲什麼min;max;從第一個例子基本上沒有操作,而x;是不是? 這是我第二次嘗試好斯卡拉?

回答

8

我寫的這一個通用版本(我曾打電話clamp),它看起來像這樣:

// NOTE: This will still do some boxing and unboxing because Ordering/Ordered is not @specialized. 
@inline def clamp[@specialized(Int, Double) T : Ordering](value: T, low: T, high: T): T = { 
    import Ordered._ 
    if (value < low) low else if (value > high) high else value 
} 

在Scala中,一個表達式的結果是在表達式中提到的最後一個值。 if-expression在第一次嘗試中的結果將被丟棄,因爲每個if-expression後面跟着另一個表達式。你的第二次嘗試是可以的,但你可以用if ... else這樣做,就像我的例子。你可以寫你是這樣的:

def limit(x: Double, min: Double, max: Double): Double = 
    if (x < min) min else if (x > max) max else x 
+0

我想知道是否可以做一個通用版本。感謝您發佈您的消息,我不知道「訂購」特質! – Chris 2011-06-01 10:37:06

+0

注意這一點,即使是專業化,從類型類型'Numeric'和'Ordered'拉入隱式中綴操作符也會導致6倍速度下降。你最好使用'Ordering'通過命名隱式而不是上下文綁定,然後使用'Ordering.min'和'Ordering.max'方法 – 2011-06-01 17:40:10

+0

@Kevin是的,這就是爲什麼NOTE註釋在我的代碼中;不幸的是,專業化並沒有真正的幫助,因爲'Ordering'和'Ordered'沒有專門化...... – Jesper 2011-06-01 18:53:45

7

如果不指定return明確,則返回值是最後一個表達式的結果。在你的第一個例子中,你的最後一個表達式是x;,所以它會在任何情況下返回。如果你想返回不同的值,那麼你可以使用if/else if/else

def limit(x : Double, min: Double, max : Double) = 
    if (x < min) min 
    else if (x > max) max 
    else x 

在這種情況下if/else if/else被視爲返回單一值單一的表達。

您也可以使用這樣的模式匹配(它也是一個表達式):

def limit(x : Double, min: Double, max : Double) = x match { 
    case x if x < min => min 
    case x if x > max => max 
    case _ => x 
} 

我不認爲你的第二個例子可以被描述爲「好階」。在這種簡單的情況下,它使整個事情複雜化,並有3個回報點(而不是單一回報點)。它也增加了更多不必要的樣板。

3

爲什麼不乾脆:

import math.{min, max} 
val limited = min(max(lower, x), upper) 

val limited = (lower max x) min upper 
12

甚至:

val limited = lower max x min upper 

maxmin具有相同的優先級和準離開,所以沒有括號需要

+3

對於那些可能會感到困惑的人來說,'lower'是下界的變量,'upper'是上界的變量,'x'是變量被限制,'max'和'min'是Int類。 – cdmckay 2015-08-27 23:15:58