与类型擦除类型匹配的部分函数
Partial function matching a type erased type
在下面的代码中,我希望仅当 i
的类型为 A
时才调用 hitA
。要检查的类型作为类型参数提供,因此它被类型擦除并且 match
失败,给我一个编译器警告:
abstract type pattern T is unchecked since it is eliminated by erasure
代码的期望输出是:
Hit A
Not hit
在当前版本中,当我 运行 代码时,我得到 Hit A 后跟 ClassCastException
。
我明白发生了什么以及为什么会出现警告和异常,但我不确定如何解决这个问题。我已经阅读了关于 TypeTags 的基本文章,并且我了解如何在基本情况下使用它们,但是我看不出如何使用 TypeTags 创建部分函数。
import scala.reflect.runtime.universe._
object TestMatch extends App {
abstract class I
class A extends I {
def hitA() = println("Hit A")
}
class B extends I
def processOpGen[T <: I : TypeTag](op: PartialFunction[I, Unit])(i: I) = {
val fallback : PartialFunction[I, Unit] = {case _ => println("Not hit")}
(op orElse fallback)(i)
}
def partialMatchGen[T <: I : TypeTag](op: T => Unit)(i: I) = {
processOpGen[T] {
case c: T => op(c) // can TypeTag be used here for matching somehow?
}(i)
}
partialMatchGen[A](a => a.hitA())(new A)
partialMatchGen[A](a => a.hitA())(new B)
}
就replace TypeTag
with ClassTag
:
import scala.reflect._
object Main extends App {
abstract class I
class A extends I {
def hitA() = println("Hit A")
}
class B extends I
def processOpGen[T <: I : ClassTag](op: PartialFunction[I, Unit])(i: I) = {
val fallback : PartialFunction[I, Unit] = {case _ => println("Not hit")}
(op orElse fallback)(i)
}
def partialMatchGen[T <: I : ClassTag](op: T => Unit)(i: I) = {
processOpGen[T] {
case c: T => op(c) // can TypeTag be used here for matching somehow?
}(i)
}
partialMatchGen[A](a => a.hitA())(new A)
partialMatchGen[A](a => a.hitA())(new B)
}
Processing...
Reused last reload result
[info] Loading project definition from /tmp/rendererL3zBdh8HOA/project/project
[info] Loading project definition from /tmp/rendererL3zBdh8HOA/project
[info] Set current project to rendererWorker (in build file:/tmp/rendererL3zBdh8HOA/)
[info] Reapplying settings...
[info] Set current project to rendererWorker (in build file:/tmp/rendererL3zBdh8HOA/)
[info] Formatting 1 Scala source {file:/tmp/rendererL3zBdh8HOA/}rendererWorker(compile) ...
[warn] Scalariform parser error for /tmp/rendererL3zBdh8HOA/src/main/scala/test.scala: Expected token RBRACKET but got Token(XML_START_OPEN,<,335,<)
[info] Compiling 1 Scala source to /tmp/rendererL3zBdh8HOA/target/classes...
[success] Total time: 11 s, completed Oct 13, 2015 5:16:45 PM
Now running...
[info] Running Main
Hit A
Not hit
[success] Total time: 0 s, completed Oct 13, 2015 5:16:45 PM
在下面的代码中,我希望仅当 i
的类型为 A
时才调用 hitA
。要检查的类型作为类型参数提供,因此它被类型擦除并且 match
失败,给我一个编译器警告:
abstract type pattern T is unchecked since it is eliminated by erasure
代码的期望输出是:
Hit A
Not hit
在当前版本中,当我 运行 代码时,我得到 Hit A 后跟 ClassCastException
。
我明白发生了什么以及为什么会出现警告和异常,但我不确定如何解决这个问题。我已经阅读了关于 TypeTags 的基本文章,并且我了解如何在基本情况下使用它们,但是我看不出如何使用 TypeTags 创建部分函数。
import scala.reflect.runtime.universe._
object TestMatch extends App {
abstract class I
class A extends I {
def hitA() = println("Hit A")
}
class B extends I
def processOpGen[T <: I : TypeTag](op: PartialFunction[I, Unit])(i: I) = {
val fallback : PartialFunction[I, Unit] = {case _ => println("Not hit")}
(op orElse fallback)(i)
}
def partialMatchGen[T <: I : TypeTag](op: T => Unit)(i: I) = {
processOpGen[T] {
case c: T => op(c) // can TypeTag be used here for matching somehow?
}(i)
}
partialMatchGen[A](a => a.hitA())(new A)
partialMatchGen[A](a => a.hitA())(new B)
}
就replace TypeTag
with ClassTag
:
import scala.reflect._
object Main extends App {
abstract class I
class A extends I {
def hitA() = println("Hit A")
}
class B extends I
def processOpGen[T <: I : ClassTag](op: PartialFunction[I, Unit])(i: I) = {
val fallback : PartialFunction[I, Unit] = {case _ => println("Not hit")}
(op orElse fallback)(i)
}
def partialMatchGen[T <: I : ClassTag](op: T => Unit)(i: I) = {
processOpGen[T] {
case c: T => op(c) // can TypeTag be used here for matching somehow?
}(i)
}
partialMatchGen[A](a => a.hitA())(new A)
partialMatchGen[A](a => a.hitA())(new B)
}
Processing...
Reused last reload result
[info] Loading project definition from /tmp/rendererL3zBdh8HOA/project/project
[info] Loading project definition from /tmp/rendererL3zBdh8HOA/project
[info] Set current project to rendererWorker (in build file:/tmp/rendererL3zBdh8HOA/)
[info] Reapplying settings...
[info] Set current project to rendererWorker (in build file:/tmp/rendererL3zBdh8HOA/)
[info] Formatting 1 Scala source {file:/tmp/rendererL3zBdh8HOA/}rendererWorker(compile) ...
[warn] Scalariform parser error for /tmp/rendererL3zBdh8HOA/src/main/scala/test.scala: Expected token RBRACKET but got Token(XML_START_OPEN,<,335,<)
[info] Compiling 1 Scala source to /tmp/rendererL3zBdh8HOA/target/classes...
[success] Total time: 11 s, completed Oct 13, 2015 5:16:45 PM
Now running...
[info] Running Main
Hit A
Not hit
[success] Total time: 0 s, completed Oct 13, 2015 5:16:45 PM