下面的代码正在使用ZIO,所以我添加了scalaz标签,尽管这可能与重点无关。我有一个函数,类型为J
,带有类型类约束(Job
):
def execJvm2[J: Job](cmdIn: J): IO[Nothing, Future[RunResult]] = {
type IOJob = IO[Nothing, J]
val cmd0: IOJob = omitted(cmdIn)
val cmd1: IOJob = cmd0.map {
case cmd : OneShot =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd.asInstanceOf[J]
case cmd: Repl =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd.asInstanceOf[J]
case cmd: ExecFile =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd.asInstanceOf[J]
case _ => ???
}
cmd1.map { cmd => poll(cmd.id) }
}
模式匹配(OneShot
,Repl
,ExecFile
)中的示例都是Job
的实例,并且它们的隐式类型类实例在范围内,尽管我猜想有点离题。我认为,在不使用asInstanceOf
的情况下应该可以工作的主要原因是,该类型仅在模式匹配中从J
缩小为例如OneShot
,但我认为编译器也会知道它仍然是J
。
答案 0 :(得分:3)
看起来有点糟,但我认为
val cmd1: IOJob = cmd0.map { cmdJ => cmdJ match {
case cmd: OneShot =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmdJ
case cmd: Repl =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmdJ
case cmd: ExecFile =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmdJ
case _ => ???
}}
应该工作。加上类型擦除作弊,我认为这应该可以编译并起作用(但可以尝试):
val cmd1: IOJob = cmd0.map {
case cmd: OneShot with J @unchecked =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd
case cmd: Repl with J @unchecked =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd
case cmd: ExecFile with J @unchecked =>
memStorage(cmd.id) = JobWithResult(cmd, runIO(runInSystem(cmd)))
cmd
case _ => ???
}