抱歉,如果这很明显,但我是 scala 的新手,并且使用以下代码出现了两个意外行为:
Seq(1, "a", 2, "b") map {
case i: Int => i+1
}
1) 我本来希望得到一个字符串不变且数字增加 1 的集合,但我得到了一个错误。
2)我相信case i: Int => i + 1
语法代表了为 Ints 定义的部分函数。但似乎 map 需要一个总函数,那为什么还要编译呢?编译器帮助我不是更好吗?将运行时异常转移到编译时异常总是更好。
抱歉,如果这很明显,但我是 scala 的新手,并且使用以下代码出现了两个意外行为:
Seq(1, "a", 2, "b") map {
case i: Int => i+1
}
1) 我本来希望得到一个字符串不变且数字增加 1 的集合,但我得到了一个错误。
2)我相信case i: Int => i + 1
语法代表了为 Ints 定义的部分函数。但似乎 map 需要一个总函数,那为什么还要编译呢?编译器帮助我不是更好吗?将运行时异常转移到编译时异常总是更好。
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()
不这样做。
尝试
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 }
编译的原因是因为 type of Seq(1, "a", 2, "b")
is 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]
。