为什么提供部分函数来映射在运行时抛出而不是给出编译错误?
Why does providing a partial function to map throw at runtime rather than give a compile error?
抱歉,如果这很明显,但我是 scala 的新手,我使用以下代码遇到了两个意外行为:
Seq(1, "a", 2, "b") map {
case i: Int => i+1
}
1) 我本希望取回一个字符串未更改且数字递增 1 的集合,但我却收到错误消息。
2) 我相信 case i: Int => i + 1
语法表示为 Ints 定义的偏函数。但似乎 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 }
编译的原因是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]
.
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
。换句话说,偏函数是一种函数。
还值得注意的是,在处理偏函数时...
It is the responsibility of the caller to call isDefinedAt
before calling apply
...
所以我们可以得出结论,collect()
做到了,而 map()
没有。
抱歉,如果这很明显,但我是 scala 的新手,我使用以下代码遇到了两个意外行为:
Seq(1, "a", 2, "b") map {
case i: Int => i+1
}
1) 我本希望取回一个字符串未更改且数字递增 1 的集合,但我却收到错误消息。
2) 我相信 case i: Int => i + 1
语法表示为 Ints 定义的偏函数。但似乎 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 }
编译的原因是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]
.
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
。换句话说,偏函数是一种函数。
还值得注意的是,在处理偏函数时...
It is the responsibility of the caller to call
isDefinedAt
before callingapply
...
所以我们可以得出结论,collect()
做到了,而 map()
没有。