簡體   English   中英

Scala:錯誤類型不匹配

[英]Scala: Error type mismatch

我正在努力使用類型系統。 我在行中收到“錯誤:類型不匹配”

handler.addJob(job1)

它說found "MessageEvent" required "Event"

我認為我需要以某種方式更改addJob方法,以使用擴展Event的類型傳遞任何Job ,但我不知道該怎么做。

還行

var jobs = List[Job[Event]]()

應該使用Event的子類型來工作,但我又不知道該怎么做。 任何幫助表示贊賞。

-埃里克

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

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

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

class Job[T <: Event] {
  var steps = List[(T => Unit)]()

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

  def processEvent(event: T): Boolean = {
    steps.foreach(_.apply(event))
    return true
  }
}

class AppTest {
  def testApp {
    val handler = new EventHandler()
    val job1 = new Job[MessageEvent]
    job1.addStep {
      println(_)
    }
    handler.addJob(job1)
    handler.receive(new MessageEvent(new Message()))
  }
}

您提到的問題很容易解決:

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

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

  def addJob(job: Job[_]) {
    jobs = job :: jobs
  }
}

但這顯示了receive方法的另一個問題:您需要每個job來處理任何Event 可以使用Manifest來解決此問題,以解決類型擦除:

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
  }
}

更改addJobs

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

jobs不與任何工作,因為Job[MessageEvent]不是Job[Event] 達到此目的的唯一方法是使Job協變,但是不幸的是,您無法使Job保持原樣。

您為什么不完全刪除Job的參數並在內部使用Event 然后,可以在addJobT <: Event (如上述addJob )與addStepprocessEvent使用。

根據您的示例,似乎您將靜態構建JobEventHandler實例。 在這種情況下,您實際上根本不需要這些類!

Job開始。 它扮演兩個角色:

  1. 維護T => Unit功能的列表
  2. 執行那些功能

(這也是值得注意的是::預先考慮,所以步驟將加入他們的順序相反被執行)

如果您已經知道事物在編譯時會變成什么樣子,則可以完全避免在運行時建立和維護該函數列表(在可變列表內)。 這最自然地是通過聚合函數完成的:

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

而不是持有List[Job[Event]] ,這意味着EventHandler現在持有List[(T => Unit)] (就像Job以前所做的那樣)。 所以沖洗並重復...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM