Scala:错误类型不匹配
我正在与类型系统作斗争。我在该行收到“错误:类型不匹配”,
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()))
}
}
I am struggling with the type system. I get a "error: type mismatch" at the line
handler.addJob(job1)
It says found "MessageEvent" required "Event"
I think that I need to somehow change the addJob
method to pass in any Job
with a type that extends Event
but I can't figure out how to do that.
Also the line
var jobs = List[Job[Event]]()
should probably take a job with a subtype of Event
but again I don't know how to do that. Any help is appreciated.
-Eric
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()))
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您提到的问题很容易解决:
但这显示了
receive
方法的另一个问题:您需要每个job
来处理任何Event
。可以使用Manifest
解决类型擦除问题:The problems you mention are easy to fix:
But this shows another problem with the
receive
method: you need eachjob
to process anyEvent
. This can be fixed usingManifest
s to work around type erasure:更改
addJobs
:但是
jobs
不起作用,因为Job[MessageEvent]
不是Job[Event].实现这一点的唯一方法是使
Job
成为协变体,但不幸的是,您不能按原样使Job
成为协变体。为什么不完全删除
Job
的参数化并在内部使用Event
呢?然后,如果需要,您可以将T <: Event
(如上面的addJob
)与addStep
和processEvent
一起使用。Changing
addJobs
:But
jobs
won't work with that, sinceJob[MessageEvent]
is not aJob[Event]
. The only way to get that is to makeJob
co-variant, but, unfortunately, you can't makeJob
co-variant as it is.Why don't you, instead, completely removes
Job
's parameterization and useEvent
internally? You can then useT <: Event
(like above inaddJob
) withaddStep
andprocessEvent
, if necessary.根据您的示例,您似乎将静态构建
Job
和EventHandler
实例。在这种情况下,你真的根本不需要这些课程!从
作业
开始。这执行两个角色:T => 的列表。 Unit
函数(还值得注意的是
::
前置,因此步骤将以与添加顺序相反的顺序执行)如果您已经知道编译时它们会是什么,则可以完全避免在运行时维护该函数列表(在可变列表中)。这是最自然地使用聚合函数完成的:
这意味着
EventHandler
现在持有一个List[(T),而不是持有一个
(如List[Job[Event]]
=> Unit)]Job
之前所做的那样)。所以冲洗并重复...Based on your example, it looks as though you'll be building the
Job
andEventHandler
instances statically. In this case, you really don't need those classes at all!Starting with
Job
. This performs two roles:T => Unit
functions(it's also worth noting that
::
prepends, so steps will be executed in the reverse of the order they were added)Building and maintaining that list of functions at runtime (within a mutable list) can be completely avoided if you already know what they'll be when the thing compiles. This is most naturally done with an aggregate function:
Instead of holding a
List[Job[Event]]
, this means thatEventHandler
now holds aList[(T => Unit)]
(asJob
previously did). So rinse and repeat...