我想在Scala中做到这一点:
def sum[T](seq: Seq[T]): T =
seq match {
case last :: Nil => last
case head :: tail => head + sum(tail)
}
但是Scala抱怨sum(tail)
上存在类型不匹配:它期望String
但得到T
-这听起来当然不正确。我研究了一下,看来Scala的类型推断系统只能推断tail
的类型为Seq[Any]
。那是问题吗?用Scala编写此代码的正确方法是什么?
答案 0 :(得分:6)
问题是编译器不知道方法+
是否可用于类型T
。关于String
的事情具有误导性。它只是默认假定+
应该是String
的串联。
如果您将T
限制为只能加在一起的某种数字类型,那么它将起作用。
def sum[T:Numeric](seq: Seq[T]): T =
seq match {
case last :: Nil => last
case head :: tail => implicitly[Numeric[T]].plus(head, sum(tail))
}
可以通过添加导入将其表达得更加简洁。
def sum[T:Numeric](seq: Seq[T]): T = {
import Numeric.Implicits._
seq match {
case last :: Nil => last
case head :: tail => head + sum(tail)
}
}
此外,::
适用于List
操作。由于您的方法适用于Seq
或List
,但不适用于Vector
。将::
更改为更通用的+:
,它将可以使用更多的集合类型,例如Vector
,Array
等。