scala - 删除类型字段

标签 scala type-erasure

abstract class Handler {
  type Message

  def handleAny(msg: Any) {
    if (msg.isInstanceOf[Message]) handle(msg.asInstanceOf[Message]) // fix me!
  }

  def handle(msg: Message)
}

class StringHandler extends Handler {
  override type Message = String

  def handle(msg: Message) { println(s"handling: $msg") }
}

val h = new StringHandler
h.handleAny("ahoj")
h.handleAny(true)

warning: abstract type Handler.this.Message is unchecked since it is
 eliminated by erasure
                if(msg.isInstanceOf[Message]) handle(msg.asInstanceOf[Message])
                                   ^
one warning found
handling: ahoj
java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
        at Main$$anon$1$StringHandler.handle(typeProblem.scala:11)
        at Main$$anon$1$Handler.handleAny(typeProblem.scala:5)

如何更改代码段(不更改接口(interface)或用类型参数替换类型字段)以按预期工作,即仅处理由类型字段指定的消息

我正在寻找一种可以应用于父抽象类而不是污染所有子类的解决方案。

我还尝试使用match,它的行为完全相同。或者这种事情对于类型字段来说是不可能的(我认为它们比类型参数更强大)?​​

最佳答案

通常使用匹配项,在您的情况下,因为您不想添加任何类型参数,所以您必须指定 ClassTag (我认为)。

大致如下:

import scala.reflect.ClassTag

abstract class Handler {
  type Message <: Any
  implicit val tag: ClassTag[Message]

  def handleAny(msg: Any): Unit = {
    msg match {
      case tag(message) =>
        handle(message)
      case _ =>
        throw new IllegalArgumentException(s"Argmument MUST BE a 'Message' but $msg is not!")
    }
  }

  def handle(msg: Message): Unit
}

object StringHandler extends Handler {
  override type Message = String
  // lazy is important here!
  implicit lazy val tag: ClassTag[Message] = ClassTag(classOf[String])

  def handle(msg: Message): Unit =  { println(s"handling: $msg") }
}


StringHandler.handleAny("ahoj")
StringHandler.handleAny(true)

关于scala - 删除类型字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35533933/

相关文章:

scala - 内联时缺少编译/运行时错误

java - 我们如何在Java中看到编译器生成的用于类型删除的字节码

scala 类型删除和值类

Scala:如何使案例类副本保留 list 信息

scala - 巧妙处理 Spark RDD 中的 Option[T]

scala - 如何将 IDEA 配置为自动将 => 替换为 ⇒ 和 -> 替换为 →?

scala - scala 中的递归排序与尾递归

scala - 你如何使用 scalamock 来模拟带有构造函数参数的类

Java 通用对象重用

java - 如何引用内部类成员的泛型类型?