Scala:错误类型不匹配

Scala:错误类型不匹配,scala,Scala,我正在与打字系统作斗争。我在行中得到一个“错误:类型不匹配” handler.addJob(job1) 它说找到“MessageEvent”需要“Event” 我认为我需要以某种方式更改addJob方法,以传入任何Job,其类型扩展为Event,但我不知道如何做到这一点 还有那条线 var jobs = List[Job[Event]]() 可能应该接受一个子类型为Event的工作,但我也不知道怎么做。感谢您的帮助 -埃里克 类事件处理程序{ 变量作业=列表[作业[事件]]() def接收(

我正在与打字系统作斗争。我在行中得到一个“错误:类型不匹配”

handler.addJob(job1)
它说
找到“MessageEvent”需要“Event”

我认为我需要以某种方式更改
addJob
方法,以传入任何
Job
,其类型扩展为
Event
,但我不知道如何做到这一点

还有那条线

var jobs = List[Job[Event]]()
可能应该接受一个子类型为
Event
的工作,但我也不知道怎么做。感谢您的帮助

-埃里克

类事件处理程序{
变量作业=列表[作业[事件]]()
def接收(事件:事件){
乔布斯·弗雷奇{
_.processEvent(事件)
}
}
def addJob(作业:作业[事件]){
作业=作业::作业
}
}
班级作业[T单元]()
def添加步骤(步骤:(T=>单位)){
步骤=步骤::步骤
}
def processEvent(事件:T):布尔={
步骤.foreach(u0.apply(事件))
返回真值
}
}
类应用程序测试{
def testApp{
val handler=new EventHandler()
val job1=新作业[MessageEvent]
job1.addStep{
println(u)
}
handler.addJob(job1)
handler.receive(newmessageevent(newmessage()))
}
}

您提到的问题很容易解决:

class EventHandler {
  var jobs = List[Job[_]]()

  def receive(event: Event) {
    jobs.foreach {
      _.processEvent(event)
    }
  }

  def addJob(job: Job[_]) {
    jobs = job :: jobs
  }
}
但是这显示了
receive
方法的另一个问题:您需要每个
作业
来处理任何
事件
。可以使用
Manifest
s解决类型擦除问题:

class Job[T <: Event : ClassManifest] {
  val clazz: Class[T] = implicitly[ClassManifest[T]].asInstanceOf[Class[T]]
  var steps = List[(T => Unit)]()

  def addStep(step: (T => Unit)) {
    steps = step :: steps
  }

  def processEvent1(event: Event): Boolean = {
    try {
      processEvent(clazz.cast(event))
    }
    catch {
      case e: ClassCastException => false
    }
  }

  def processEvent(event: T): Boolean = {
    steps.foreach(_.apply(event))
    return true
  }
}
class作业[T单元]()
def添加步骤(步骤:(T=>单位)){
步骤=步骤::步骤
}
def processEvent1(事件:事件):布尔={
试一试{
processEvent(clazz.cast(事件))
}
抓住{
案例e:ClassCastException=>false
}
}
def processEvent(事件:T):布尔={
步骤.foreach(u0.apply(事件))
返回真值
}
}

您提到的问题很容易解决:

class EventHandler {
  var jobs = List[Job[_]]()

  def receive(event: Event) {
    jobs.foreach {
      _.processEvent(event)
    }
  }

  def addJob(job: Job[_]) {
    jobs = job :: jobs
  }
}
但是这显示了
receive
方法的另一个问题:您需要每个
作业
来处理任何
事件
。可以使用
Manifest
s解决类型擦除问题:

class Job[T <: Event : ClassManifest] {
  val clazz: Class[T] = implicitly[ClassManifest[T]].asInstanceOf[Class[T]]
  var steps = List[(T => Unit)]()

  def addStep(step: (T => Unit)) {
    steps = step :: steps
  }

  def processEvent1(event: Event): Boolean = {
    try {
      processEvent(clazz.cast(event))
    }
    catch {
      case e: ClassCastException => false
    }
  }

  def processEvent(event: T): Boolean = {
    steps.foreach(_.apply(event))
    return true
  }
}
class作业[T单元]()
def添加步骤(步骤:(T=>单位)){
步骤=步骤::步骤
}
def processEvent1(事件:事件):布尔={
试一试{
processEvent(clazz.cast(事件))
}
抓住{
案例e:ClassCastException=>false
}
}
def processEvent(事件:T):布尔={
步骤.foreach(u0.apply(事件))
返回真值
}
}

更改
添加作业

def addJob[T <: Event](job: Job[T]) {
  jobs = job :: jobs
}

def addJob[T更改
addJobs

def addJob[T <: Event](job: Job[T]) {
  jobs = job :: jobs
}

def addJob[T根据您的示例,看起来您将静态地构建
Job
EventHandler
实例。在这种情况下,您根本不需要这些类

从作业开始。它执行两个角色:

  • 维护
    T=>Unit
    功能列表
  • 执行这些功能
  • (还值得注意的是,
    会在前面加上前缀,因此步骤的执行顺序与添加顺序相反)

    如果您已经知道编译时函数将是什么,那么在运行时(在可变列表中)构建和维护该函数列表是完全可以避免的。这是使用聚合函数最自然的做法:

    val job = (m: MessageEvent) => {
      log.debug(m)
      println(m)
      somethingElse(m)
    }
    

    这意味着
    EventHandler
    现在持有
    List[(T=>Unit)]
    (与
    Job
    以前一样)而不是持有
    List[Job[Event]]
    。因此,冲洗并重复…

    基于您的示例,看起来您将静态地构建
    作业
    事件处理程序
    实例。在这种情况下,您根本不需要这些类

    从作业开始。它执行两个角色:

  • 维护
    T=>Unit
    功能列表
  • 执行这些功能
  • (还值得注意的是,
    会在前面加上前缀,因此步骤的执行顺序与添加顺序相反)

    如果您已经知道编译时函数将是什么,那么在运行时(在可变列表中)构建和维护该函数列表是完全可以避免的。这是使用聚合函数最自然的做法:

    val job = (m: MessageEvent) => {
      log.debug(m)
      println(m)
      somethingElse(m)
    }
    

    这意味着
    EventHandler
    现在不再持有
    List[Job[Event]]
    ,而是持有
    List[(T=>Unit)]
    (正如
    Job
    之前所做的那样)。因此,冲洗并重复…

    非常感谢Alexey的帮助!如果你喜欢答案,你应该投票(请参阅常见问题解答“我如何在这里提问?”).非常感谢您的帮助Alexey!如果您喜欢答案,您应该投票表决(请参阅常见问题解答“我如何在此处提问?”)。