[英]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
? 然后,可以在addJob
將T <: Event
(如上述addJob
)與addStep
和processEvent
使用。
根據您的示例,似乎您將靜態構建Job
和EventHandler
實例。 在這種情況下,您實際上根本不需要這些類!
從Job
開始。 它扮演兩個角色:
T => Unit
功能的列表 (這也是值得注意的是::
預先考慮,所以步驟將加入他們的順序相反被執行)
如果您已經知道事物在編譯時會變成什么樣子,則可以完全避免在運行時建立和維護該函數列表(在可變列表內)。 這最自然地是通過聚合函數完成的:
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.