我有这样的事情:
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
。
怎么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
。它涉及一些相当深的编译器魔术,魔术总是要付出代价的。就个人而言,我倾向于使用您的原始方法,因为涉及的魔术较少。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句