我有大量简单的命令行 Scala 应用程序,它们共享相当多的通用结构。它们都继承自 scala.App,这很好。我想将这些命令行应用程序的共享结构重构为一个共同的特征,然后我可以将其继承到我的(更简单的)命令行应用程序类中。问题在于一些常见结构包括命令行参数的解析。
object MyScript extends BaseScript with App{
//small bits of business logic using components defined in BaseScript
}
trait BaseScript extends App{
val configuration = loadConfiguration(args(0))
//setup a bezillion components, usable from any of the scripts, based on the configuration
}
这可以编译,但在实际取消引用时会因 NPE 失败
args
,大概是因为 App
trait 尚未初始化。改变 trait 顺序并将 BaseScript 中 App 的继承更改为自类型声明没有任何作用,就像 DelayedInit 的实验一样。在 BaseScript 中将组件声明为“lazy”是可行的,但我也希望在初始化期间实际使用这些组件(例如,根据配置设置日志目录和加载 JDBC 驱动程序类),因此失去了惰性的好处。我可以做些什么来使命令行参数在 BaseScript 特征中可见并初始化?
最佳答案
我认为你最好的办法是改变你的 BaseScript
trait 变成一个类有两个原因。第一个是与类相比,特征初始化以相反的顺序执行 .见 this question on initialization behavior .二、BaseScript
语义上更像是一个父类(super class)而不是额外的行为。我想你会发现这可以简化事情。
执行 MyScript
时,以下代码初始化BaseScript
先上课。 BaseScript
依赖于 App
特质依次并强制它首先初始化。
object MyScript extends BaseScript {
//small bits of business logic using components defined in BaseScript
println( "running" )
println( "arg(0): " + configuration )
}
class BaseScript extends App {
val configuration = loadConfiguration(args)
//setup a bezillion components, usable from any of the scripts, based on the configuration
def loadConfiguration( args: Array[String] ) = {
println( "configuring" )
if ( args.length > 0 ) args(0) else null
}
}
关于scala - 在 Scala 特征中获取命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8391449/