我有这样的事情:
abstract class RunnerBase { def printErrorAndBreak = ... }
object Runner1 extends RunnerBase {
breakable {
doSomething
if (cond1) printErrorAndBreak(...)
}
}
object Runner2 extends RunnerBase {
breakable {
if (cond1) printErrorAndBreak(...)
something else
}
}
我想将breakable { ... }
部分移到RunnerBase
,以便Runner1
和Runner2
看起来像这样:
object Runner1 extends RunnerBase {
doSomething
if (cond1) printErrorAndBreak(...)
}
object Runner2 extends RunnerBase {
if (cond1) printErrorAndBreak(...)
something else
}
这甚至可能吗?或者是我将子对象逻辑包装在一个run
方法中的唯一方法吗?
更新:根据已接受的答案(无论评论如何),为了稳健和简单起见,我决定采用这种方式:
class RunnerBase { def run = breakable _ }
class Runner1 { run { doSmth; if (?) printErrorAndBreak } }
class Runner2 { run { doSmth; if (?) printErrorAndBreak } }
不完美,因为仍有run { ... }
次重复,但至少breakable
和break
已封装在RunnerBase
中。
答案 0 :(得分:2)
DelayedInit
怎么样?
import scala.util.control.Breaks._
trait BreakInit extends DelayedInit {
def delayedInit(body: => Unit) {
breakable {body}
}
}
class MyClass extends BreakInit {
println("Hello World")
break()
println("Error - should not be reachable")
}
val a = new MyClass
在这种情况下,我们创建了一个继承自BreakInit
的特征DelayedInit
,它会覆盖delayedInit
方法以调用breakable
块中的构造函数。然后将MyClass
的构造函数汇总到一个函数中,并传递给delayedInit
方法。正如@ som-snytt指出的那样,DelayedInit
魔法只影响类构造函数,而不影响特征构造函数。
但是,在使用DelayedInit
时,我建议您注意一下。它涉及一些相当深度的编译器魔法,魔法总是带来价格。就个人而言,我倾向于更喜欢你原来的方法,因为涉及的魔法较少。