我想要一个通用函数来对列表中的值求和。斯卡拉数值总和列表
下面的代码无法编译:
def sum[T : Numeric](x: List[T]): T = {
if(x.isEmpty) 0
else x.head + sum(x.tail)
}
的编译错误是:
error: type mismatch;
[INFO] found : Int(0)
[INFO] required: T
[INFO] if(x.isEmpty) 0
我想要一个通用函数来对列表中的值求和。斯卡拉数值总和列表
下面的代码无法编译:
def sum[T : Numeric](x: List[T]): T = {
if(x.isEmpty) 0
else x.head + sum(x.tail)
}
的编译错误是:
error: type mismatch;
[INFO] found : Int(0)
[INFO] required: T
[INFO] if(x.isEmpty) 0
此错误是告诉你,你所指定的返回类型为T
,但你总是返回一个0
作为空列表,这是一个Int
。如果传入的列表包含其他内容,例如T
是Double
还是某种自定义类型?试试这个:
if(x.isEmpty) implicitly[Numeric[T]].zero
完整的工作方法:
def sum[T : Numeric](x: List[T]): T = {
if (x.isEmpty) implicitly[Numeric[T]].zero
else implicitly[Numeric[T]].plus(x.head, sum(x.tail))
}
或者:
def sum[T](x: List[T])(implicit num: Numeric[T]): T = {
import num._
if (x.isEmpty) zero
else x.head + sum(x.tail)
}
试试这个:
def sum[T](x: List[T])(implicit num: Numeric[T]): T = x.foldLeft(num.zero)(num.plus)
使用reduce
(如果你不想设置对于总和ITAL值)以其他方式使用fold
操作:
def sumWithReduce[T](lst: List[T])(implicit numericType: Numeric[T]):T
= lst.reduce(numericType.plus)
def sumWithFold[T](lst: List[T])(implicit numericType: Numeric[T]):T
= lst.fold(numericType.zero)(numericType.plus)
'reduce'失败的空列表,'fold'更强大。 –
为什么不使用'x.sum'(其中'x'是一个'列表[T]'和'T'有一个隐式'数值[T] '定义的实例)? –
我在网上遇到了代码片断,并对我如何使它更通用感到好奇。这是一个了解斯卡拉的练习(我不在学校,只是好奇) – Jake
顺便说一句,有一件事要注意这种类型的功能:它不是_tail递归_。如果你有一个很长的列表,你可以得到一个_stack overflow_。 (现在我在哪里听到过这个表达式?)对于函数是尾递归的,递归调用必须是最后一个表达式。 –