【问题标题】:Scala Match Error On Tuple With Parameterized Type具有参数化类型的元组上的 Scala 匹配错误
【发布时间】:2015-10-29 14:11:14
【问题描述】:

我正在尝试使用参数化基类为各种类型编写一些通用测试软件。尽管在我认为不可能的代码上出现匹配错误。

abstract class AbstractTypeTest[TestType: ClassTag, DriverType <: AnyRef : ClassTag]( 
  def checkNormalRowConsistency(
    expectedKeys: Seq[TestType],
    results: Seq[(TestType, TestType, TestType)]) {

    val foundKeys = results.filter {
      case (pkey: TestType, ckey: TestType, data: TestType) => expectedKeys.contains(pkey)
      case x => throw new RuntimeException(s"${x.getClass}")
    }
    foundKeys should contain theSameElementsAs expectedKeys.map(x => (x, x, x))
  }
}

一个扩展类指定了 TypeTest 的参数,但是这个代码块抛出了运行时异常(因为我们不匹配我认为应该是这里唯一允许的类型)

上面代码的输出带有一些扩展类型,但对于其他类型则不起作用,在这种情况下,我使用 TestType 扩展这个类 --> Int

[info]   java.lang.RuntimeException: class scala.Tuple3

我可以删除过滤器上的类型,ScalaTest 检查工作正常,但我想了解为什么会发生 MatchError。

【问题讨论】:

  • 您传递给results 的运行时类型很可能与模式不匹配(例如,当您使用asInstanceOf 时可能会发生这种情况。您能否提供一个调用@987654325 的示例代码@ 让它抛出这个异常?
  • 可能是这样,它使用了一些相当复杂的内部函数来生成输入。 val result = sc.cassandraTable[(TestType, TestType, TestType)](keyspaceName, table).collect 在 Spark 端调用一些类型转换器,然后应该通过序列化返回 List[(TestType,TestType,TestType)]
  • 这在常规 Scala 中确实有效,而且它看起来不像我一开始怀疑的类型擦除。您可以查看字节码以了解传递给它的内容。

标签: scala inheritance types


【解决方案1】:

如果您使用的是 Scala 2.10,那么

ClassTag based pattern matching fails for primitives

scala> import reflect._
import reflect._

scala> def f[A: ClassTag](as: Seq[(A,A,A)]) = as filter {
     | case (x: A, y: A, z: A) => true ; case _ => false }
f: [A](as: Seq[(A, A, A)])(implicit evidence$1: scala.reflect.ClassTag[A])Seq[(A, A, A)]

scala> val vs = List((1,2,3),(4,5,6))
vs: List[(Int, Int, Int)] = List((1,2,3), (4,5,6))

scala> f(vs)
res0: Seq[(Int, Int, Int)] = List()

与 2.11 相比

scala> f[Int](vs)
res4: Seq[(Int, Int, Int)] = List((1,2,3), (4,5,6))

【讨论】:

  • 谢谢!这与我所看到的完全一致。
猜你喜欢
  • 2016-04-02
  • 1970-01-01
  • 2015-02-28
  • 2016-05-12
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多