3

抱歉,如果这很明显,但我是 scala 的新手,并且使用以下代码出现了两个意外行为:

Seq(1, "a", 2, "b") map { 
    case i: Int => i+1
}

1) 我本来希望得到一个字符串不变且数字增加 1 的集合,但我得到了一个错误。

2)我相信case i: Int => i + 1语法代表了为 Ints 定义的部分函数。但似乎 map 需要一个总函数,那为什么还要编译呢?编译器帮助我不是更好吗?将运行时异常转移到编译时异常总是更好。

4

2 回答 2

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()不这样做。

于 2019-06-19T20:42:29.570 回答
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 }编译的原因是因为 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]

于 2019-06-19T20:29:59.163 回答