2017-04-21 93 views
1

我用的方法尝试在斯卡拉这是试图取决于他们是多么大的圆号码,例如如果该值低于1,则将其舍入至少一个小数点是有意义的;而不是保留一个整数。这里就是我想:取整数值参数类型斯卡拉

def roundSmart[A](num: A)(implicit numeric: Numeric[A]) = num match { 
    case num if num < 1 => numeric.toDouble(num) 
    case _ => numeric.toInt(num) 
    } 

会抛出这个错误:

value < is not a member of type parameter A

当然的参数需要接受函数签名以内的范围参数类型的,因为它可能采取整数或双打,这增加了更多的复杂性。

我已经采取了条件声明第一情况从这个答案 - Using comparison operators in Scala's pattern matching system并很渴望使用函数式编程方法。也许还有一些内置的scala函数,如Math.round()可能有助于将第二个条件四舍五入,而不是删除任何小数。谢谢!

+0

'math.round'并在斯卡拉存在 –

回答

1

TL; DR:你需要每一个数字的方法是内部numeric

的错误是不言自明的:你的类型A(这是通用的)没有一个<方法。

但是,你有什么是与所有数字方法类型类,所以你应该将它们导入:

import numeric._ 

该进口(除其他事项外),隐式转换OrderingOps,其所需的方法。但是这种比较无法正常工作,因为1不是A,而是Int

解决方案只需使用fromIntnumeric

虽然我们在这样做,你会有意想不到的结果输入,如-234.2e123 ......你最好做你的测试你的号码的绝对值(abs也是numeric的方法)。

另外,如果你想要做一个简单的测试,也没有必要使用模式匹配,一个if else说法是不够

def roundSmart[A](num: A)(implicit numeric: Numeric[A]) = { 
    import numeric._ 
    if (abs(num) < fromInt(1)) toDouble(num) else toInt(num) 
} 
+0

注意,返回类型将是'双',你可能也想做一些这方面的事情。 –

+0

感谢您的回复。所以错误会很大 - 但是如果它总是返回一个Double,无论我是否想要一个Integer,那么它都无法完成我打算做的事情(请阅读整个问题以了解目的)。所以我必须使用错误的技术。此外,*模式匹配*是因为我将有两个以上的条件。 –

+0

由于您有静态类型,所以必须有一个定义良好的返回类型。你应该考虑你想要的是什么,这取决于你的用例。 –