2013-09-23 23 views
2

第二個實現有什麼問題?List.collect上的匹配錯誤

作品:

scala> List(1,2,3).collect{ case i: Int if i % 2 == 0 => i } 
res1: List[Int] = List(2) 

並不:

scala> val evens = PartialFunction[Any, Int]{ 
    | case i: Int if i % 2 == 0 => i 
    | } 
evens: PartialFunction[Any,Int] = <function1> 

scala> List(1,2,3).collect{evens} 
scala.MatchError: 1 (of class java.lang.Integer) 
    at $anonfun$1.apply(<console>:7) 
    at $anonfun$1.apply(<console>:7) 
    at scala.PartialFunction$$anonfun$apply$1.applyOrElse(PartialFunction.scala:242) 
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) 
    at scala.collection.TraversableLike$$anonfun$collect$1.apply(TraversableLike.scala:278) 
    at scala.collection.immutable.List.foreach(List.scala:318) 
    ... 

回答

6

您應該創建evensPartialFunction這樣的:

val evens: PartialFunction[Any, Int] = { 
    case i: Int if i % 2 == 0 => i 
} 

隨着PartialFunction[Any, Int]{ ... }您呼叫的對象PartialFunctionapply方法。它定義如下:

def apply[A, B](f: (A) ⇒ B): PartialFunction[A, B] 

所以{ case i: Int if i % 2 == 0 => i }作爲一個功能,而不是一個PartialFunctionevens在任何參數的定義:

scala> val evens = PartialFunction[Any, Int]{ 
    | case i: Int if i % 2 == 0 => i 
    | } 

scala> evens.isDefinedAt(1) 
res1: Boolean = true 

scala> val evens: PartialFunction[Any, Int] = { 
    | case i: Int if i % 2 == 0 => i 
    | } 

scala> evens.isDefinedAt(1) 
res5: Boolean = false 
1

您的代碼實際上是在斯卡拉2.9.2(模數不正確局部函數聲明)不工作。然而,在任何情況下,原因可能是類型簽名:

PartialFunction[Any, Int] 

由於第一類參數爲Any,集合元素得到autoboxed到java.lang.Integer實例 - 它甚至是這麼說的堆棧跟蹤(根據需要,自Any對應於Object)。但是,您匹配的是Int,這會導致錯誤。

使用PartialFunction[Int, Int]應該解決的問題,即:

val evens:PartialFunction[Int, Int] = {case i: Int if i % 2 == 0 => i}