2011-06-01 56 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