2

我正在尝试解析命令行参数并执行一个函数,该函数在成功提取参数后获取参数。我有一个名为 CurrencyExchangeRunner 的对象,其中主要方法是。我设想的类的结构如下:

object CurrencyExtractionRunner {
      def main(args:Array[String]){
        parseArgs(args){
            (currencyType,currencyTypeArgs) => 
                 CurrencyExchanger(curencyType,currencyTypeArgs){
                   (exchanger) => exchanger.startExchange
                 }
            }
        }
      }
   }

上面我想要完成的是使用解析参数parseArgs(args),获取(currencyType,currencyTypeArgs)as 参数并将它们传递给CurrencyExchanger工厂对象,然后返回exchanger我将在其上执行该startExchange方法的适当参数。这是我所设想的,但我对如何创建这个流程有点不知所措。我尝试的第一件事是创建一个解析命令行参数的特征,如下所示(我正在使用 jcommander 库进行命令行解析):

object Args {
    @Parameter(
      names = Array("-h", "--help"), help = true)
    var help = false
    @Parameter(
      names = Array("-c", "--currency-type"),
      description = "Type of currency exchange that needs to be performed",
      required = true)
    var currencyType: String = null
    @Parameter(
      names = Array("-d", "--denominations"),
      description = "Specific denominations to be used during the exchage")
    var exchangeDenomination: String = null
    @Parameter(
      names = Array("-s", "--someotheroptionalarg"),
      description = "Additional argument for a specific currency exchange")
    var someOtherOptionalArg: String = null

  }


trait ParseUtils {
//How do I do this, take the args and return a function.  
def parseArgs(args: Array[String]){
    val jCommander = new JCommander(Args, args.toArray: _*)
    if (Args.help) {
      jCommander.usage()
      System.exit(0)
    }
    //What do I do now? How do I proceed with executing the function with
    //the specific arguments?
    //What do I need to do to wrap the commandline arguments so that it could 
    //be passed to the next function
  }
}

我非常卡在这里,因为我不确定如何使代码足够灵活以获取命令行参数的任意序列并执行下一步,即返回的工厂接受这些参数并返回正确的交换器。

如果有人能指出我正确的方向,那就太好了。

4

1 回答 1

2

我不确定您为什么要使用这种不寻常的语法将返回值传递给以下方法。

我会寻求一个更简单的解决方案,看起来像

trait ParseUtils {
  //Why would you return a function here? 
  //Is it a strict constraint you need to fulfill?
  def parseArgs(args: Array[String]): (String, String) {
    val jCommander = new JCommander(Args, args.toArray: _*)
    if (Args.help) {
      jCommander.usage()
      System.exit(0)
    }
    //This is the return value of the method, a pair of parameters
    (Args.currencyType, Args.exchangeDenomination)
    //If you need to embed additional params, you should append them to existing one
    // or you could create optional values from the Args members...
    // e.g. (Args.currencyType, Args.exchangeDenomination, Option(Args.someOtherOptionalArg))
    //       with return type (String, String, Option[String])
  }
}

object CurrencyExtractionRunner with ParseUtils {
  def main(args:Array[String]){
    val (currencyType,currencyTypeArgs) = parseArgs(args)
    CurrencyExchanger(currencyType,currencyTypeArgs).startExchange
  }
}

case class CurrencyExchanger(currencyType: String, currencyTypeArgs: String) {
  def startExchange = //implementation details using the costructor arguments
}

替代解决方案

因为我更喜欢parseArgs“功能性”,所以我将其更改为

trait ParseUtils {
  def parseArgs(args: Array[String]): Option[(String, String)] {
    val jCommander = new JCommander(Args, args.toArray: _*)
    if (Args.help) {
      jCommander.usage()
      None
    } else 
    Some(Args.currencyType, Args.exchangeDenomination)
  }
}

object CurrencyExtractionRunner with ParseUtils {
  def main(args:Array[String]){
    parseArgs(args).foreach {
      case (currencyType,currencyTypeArgs) => 
        CurrencyExchanger(currencyType,currencyTypeArgs).startExchange
    }
  }
}

case class CurrencyExchanger(currencyType: String, currencyTypeArgs: String) {
  def startExchange = //implementation details using the costructor arguments
}
于 2013-06-08T23:03:28.587 回答