我是scala的新手。目前我正在尝试开发一个计算器作为scala项目。 但在试图找到总和时,我遇到了问题。以下代码无法编译。
def add [T](values :List[T]) : Option[T]={
if (values.isInstanceOf[String]) {
None
}
else if(values.isInstanceOf[Int] || values.isInstanceOf[Long] || values.isInstanceOf[Double]) {
Some(values.sum)
}
}
答案 0 :(得分:1)
当你对某种语言不熟悉时,重要的是要慢慢开始并发现抽象,而不是立即强加它们,而没有经验使其发挥作用。我还认为仅仅依靠标准库函数(除非你很匆忙)(如sum
)或查看第三方库是不明智的,直到您完全理解标准库提供的内容为止。
换句话说,首先让我们看看为Int
解决问题的方法:
def add(values: List[Int]) = values.reduce((a, b) => a + b)
reduce
函数有效,因为结果的类型与列表中的类型相匹配。内容为Int
s,总和为Int
。你也会发现这可以通过一些语法糖来简化:
def add(values: List[Int]) = values.reduce(_ + _)
等到你看到在Scala中使用下划线的所有方法。
在您继续学习的过程中,您会发现为了累积与不同类型的值而不是列表中的内容,您可以使用其中一个{{1} } 方法。但他们也可以在这里工作,所以例如你也可以这样做:
fold*
现在尝试为def add(values: List[Int]) = values.foldLeft(0)(_ + _)
,Long
甚至Double
定义相同的功能。您会发现实现几乎完全相同。
只有当您看到真正类似的实现时,如果不相同,您甚至应该考虑抽象。解决此问题的一个方法是type classes。然而,对于初学者来说,它们并不容易。 Daniel Westheide在这个主题上写了一篇很棒的post,坦率地说,当你学习Scala时,你会很好地阅读整个series。
我真的简化了一些事情,并且掩盖了很多主题(比如为什么String
有两个参数列表,其中第一个是0,或者那些疯狂的foldLeft
事情在Daniel&#中39; s类型的帖子),但我的建议是要耐心,慢慢行动。 Scala并不容易,但你会得到它。
(但如果你很匆忙并且你是初学者,我认为你最好只使用implicit
然后为每种类型编写单独的函数。这将是敏捷作者Kenny Rubin的一个例子。会打电话给那些必要的"或者#34;不可避免的技术债务,这些都是初学者所期待的。只需稍后重构。)
答案 1 :(得分:0)
或更通用(例如amm):
@ import $ivy.`org.typelevel:cats_2.12:0.8.1`
import $ivy.$
@ import cats._, cats.implicits._
import cats._, cats.implicits._
@ List(1, 2, 3).combineAll
res2: Int = 6
@ List("1", "2", "3").combineAll
res3: String = "123"
@ List(List(1, 2), List(), List(3)).combineAll
res5: List[Int] = List(1, 2, 3)
或通过fiddle。它的工作原理是使用Monoid和Traversable类型类。