道歉,如果这很明显,但是我是scala的新手,并且使用以下代码遇到了两种意外行为:
Seq(1, "a", 2, "b") map {
case i: Int => i+1
}
1)我本来希望返回一个字符串不变且数字加1的集合,但我得到了一个错误。
2)我相信case i: Int => i + 1
语法代表为Ints定义的部分函数。但是看来map需要一个总函数,那么为什么还要编译呢?编译器帮助我会更好吗?最好将运行时异常移至编译时间异常。
答案 0 :(得分:6)
map()
并不采用部分函数作为传递的参数,但是collect()
则采用了部分函数。
Seq(1, "a", 2, "b") collect {
case i: Int => i+1
}
//res0: Seq[Int] = List(2, 3)
请注意,未为部分功能定义的输入是如何不传递而是被丢弃的。您不希望删除的内容需要一个处理程序,即使它只是一个case _ =>
默认处理程序。
Seq(1, "a", 2, "b", 'z') collect {
case i: Int => i+1 //increment ints
case c: Char => c.toUpper //capitalize chars
case s: String => s //strings pass through
}
//res0: Seq[Any] = List(2, a, 3, b, Z)
当您将部分函数传递给map()
时,编译器不会抱怨trait PartialFunction[-A, +B] extends (A) => B
。换句话说,部分功能 是一种功能。
还值得注意的是,在处理部分函数时...
呼叫者有责任在致电
isDefinedAt
之前先致电apply
...
因此,我们可以得出结论,collect()
是这样做的,而map()
不是。
答案 1 :(得分:3)
尝试
Seq(1, "a", 2, "b") map {
case i: Int => i + 1
case any => any
}
输出
res0: Seq[Any] = List(2, a, 3, b)
Seq(1, "a", 2, "b") map { case i: Int => i + 1 }
编译的原因是因为Seq(1, "a", 2, "b")
的类型是Seq[Any]
。另一方面,以下
Seq("a", "b").map { case i: Int => i + 1 }
给出编译器错误
scrutinee is incompatible with pattern type;
[error] found : Int
[error] required: String
[error] Seq("a", "b").map { case i: Int => i + 1 }
因为Seq("a", "b")
的类型为Seq[String]
,而{ case i: Int => i + 1 }
的类型为PartialFunction[Int, Int]
。