scala - 在 Scala 特征中获取命令行参数

标签 scala

我有大量简单的命令行 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/

相关文章:

scala - 从 Scala 中的 CSV 文件加载时,我需要从数据框中跳过三行

scala - 带别名的 Spark 数据帧映射聚合?

scala - 单个 monad 的多个 flatMap 方法?

scala - 使用ProGuard缩小Scala

string - 使用替换映射替换字符串上的多个单词

scala - Hadoop 3 gcs-connector 无法在最新版本的 Spark 3 独立模式下正常工作

scala - PlayFramework Scala 测试 - 通过依赖注入(inject)器获取类的实例

scala - 家庭多态性+混合?

java - Scala 中是否有相当于 Python 的 islice 的东西?

java - Intellij 不尊重 build.sbt 中的某些选项