以下代码:
trait TestMainArgs extends App {
println(s"args are: $args") // I need to have a generic main in trait which refers to args...
}
object MyRealMainObj extends TestMainArgs {
// I do not want to call the generic main from objects this would mean I would need to call them from every object which extendfs TestMainArgs
}
打印:
args are: null
以下内容:
trait TestMainArgs extends App {
}
object MyRealMainObj extends TestMainArgs {
println(s"args are: $args")
}
打印:
args are: [Ljava.lang.String;@f82f98
那么如何从特征中访问args?
我想将"main"
的逻辑只放在超级trait
中,我不想要代码重复,比如从每个扩展应用程序超级主要的对象调用,有没有实现这一目标的方法?
答案 0 :(得分:3)
答案在于查看Scala源代码中的DelayedInit和App。真正的宝石在于DelayedInit开头的doc评论:
Example:
* {{{
* trait Helper extends DelayedInit {
* def delayedInit(body: => Unit) = {
* println("dummy text, printed before initialization of C")
* body // evaluates the initialization code of C
* }
* }
*
* class C extends Helper {
* println("this is the initialization code of C")
* }
*
* object Test extends App {
* val c = new C
* }
* }}}
*
* Should result in the following being printed:
* {{{
* dummy text, printed before initialization of C
* this is the initialization code of C
* }}}
所以,只需扩展DelayedInit,按照你在App中看到的警告(具体来说,不要覆盖扩展类中的args),你应该能够像App一样访问它们:
@deprecatedOverriding("main should not be overridden", "2.11.0")
def main(args: Array[String]) = {
this._args = args
//other stuff goes here as you like
}
但是,如果您这样做,请注意它已被弃用,就像它在那里所说的那样,因此您将面临在未来版本的Scala中丢失功能的风险。
答案 1 :(得分:3)
另一个不推荐使用的选项是覆盖main
:
trait TestMainArgs extends App {
override def main(args: Array[String]) {
println(s"args are: ${args(0)} from test")
super.main(args)
}
}
问题在于编译traits的方式,在主对象之前触发构造函数,这是设置args
的地方。似乎没有不弃用的方法来做到这一点......