我试图使用sellmerfud.optparse来解析用于启动Spark2 2-Submit jar文件的参数。下面粘贴的代码适合粘贴到闪烁2-shell中,在那里我强制使用args值,因为它们将通过命令行传递。
问题是,当我使用正在设置的try/catch变量时,没有分配给类,但是当我不使用try/catch时,args数组解析得很好,并且值是可用的,我正在粘贴我在闪烁2-shell会话中捕获的内容,以提供信息以查看发生了什么。
import org.sellmerfud.optparse._
case class Config(keyVal: String = "tst",
startDate: String = "",
endDate: String = "")
var args = Array("-k","testkey","-s","2018-01-01","-e","2018-03-31")
var clsCfg = try {
new OptionParser[Config] {
banner = "testargs [options] file...\n"
separator("")
separator("Options: ")
reqd[String]("-k <string>", "--keyval <string>", "Enter Key Value")
{ (v, cfg) => cfg.copy(keyVal = v) }
optl[String]("-s", "--startdate <date>", "Enter date in mm-dd-yyyy format.")
{ (v, cfg) => cfg.copy(startDate = v.toString()) }
optl[String]("-e", "--enddate <date>", "Enter date in mm-dd-yyyy format.")
{ (v, cfg) => cfg.copy(endDate = v.toString) }
}.parse(args, Config())
} catch { case e: OptionParserException => println(e.getMessage); java.lang.System.exit(1) }
println("clsCfg: " + clsCfg)
println("\nArguments passed as array, one array element per row:")
println(args.deep.mkString("\n"))
println("clscfg.keyVal: " + clsCfg.keyVal)从上述代码输出的行:
import org.sellmerfud.optparse._
defined class Config
args: Array[String] = Array(-k, testkey, -s, 2018-01-01, -e, 2018-03-31)
clsCfg: Any = Config(testkey,Some(2018-01-01),Some(2018-03-31))
clsCfg: Config(testkey,Some(2018-01-01),Some(2018-03-31))
Arguments passed as array, one array element per row:
-k
testkey
-s
2018-01-01
-e
2018-03-31
<console>:42: error: value keyVal is not a member of Any
println("clscfg.keyVal" + clsCfg.keyVal)但是,当我移除try/catch行时,如下所示:
import org.sellmerfud.optparse._
case class Config(keyVal: String = "tst",
startDate: String = "",
endDate: String = "")
var args = Array("-k","testkey","-s","2018-01-01","-e","2018-03-31")
var clsCfg =
new OptionParser[Config] {
banner = "testargs [options] file...\n"
separator("")
separator("Options: ")
reqd[String]("-k <string>", "--keyval <string>", "Enter Key Value")
{ (v, cfg) => cfg.copy(keyVal = v) }
optl[String]("-s", "--startdate <date>", "Enter date in mm-dd-yyyy format.")
{ (v, cfg) => cfg.copy(startDate = v.toString()) }
optl[String]("-e", "--enddate <date>", "Enter date in mm-dd-yyyy format.")
{ (v, cfg) => cfg.copy(endDate = v.toString) }
}.parse(args, Config())
println("clsCfg: " + clsCfg)
println("\nArguments passed as array, one array element per row:")
println(args.deep.mkString("\n"))
println("clscfg.keyVal: " + clsCfg.keyVal)我得到了这些结果,这确实解析了字符串,但更重要的是,它创建了变量clsCfg,在这里我可以轻松地访问类成员。
import org.sellmerfud.optparse._
defined class Config
args: Array[String] = Array(-k, testkey, -s, 2018-01-01, -e, 2018-03-31)
clsCfg: Config = Config(testkey,Some(2018-01-01),Some(2018-03-31))
clsCfg: Config(testkey,Some(2018-01-01),Some(2018-03-31))
Arguments passed as array, one array element per row:
-k
testkey
-s
2018-01-01
-e
2018-03-31
clscfg.keyVal: testkey 我认为我需要try/catch来正确地处理提交的格式错误的变量,但我不知道如何工作。任何帮助都是非常感谢的。
发布于 2018-04-12 00:39:07
正在发生的事情可以在一个例子中显示出来。基本上,当您使用try.catch时,scala将查看所有代码块(try和所有catch,因为可能有多个)的每种返回类型,并返回所有代码块共有的一个类型。在你的例子中,它是Any。示例:
val a = try { 1 } // a will be of type Int
val b = try { 1 } catch { _ => 2 } // b will be of type Int
val c = try { 1 } catch { _ => "blah" } // c will be of type Any如果您想要一种更适合scala的方法来处理它,您可以按照注释中的建议来做,并使用Try() monad,但是您可以构建一个返回Option[Config]的函数。
def buildConfig(args:Array[String]):Option[Config] = try {
Some(new OptionParser[Config] {
....
}.parse(args, Config())
} catch { _ => None } 请注意,由于Option和None都是Option,所以尝试并捕获都返回一个Option。然后使用模式匹配确保处理成功。
buildConfig(args) match {
case Some(conf) => // normal processing
case None => //
}发布于 2018-04-12 14:07:57
正如在另一个答案中提到的,try语句的返回类型是try和所有catch块结果中的常见类型。您的try会产生一个Config,但是您的catch会生成一个Unit (因为它不返回任何值),它们的常见类型是Any。您可以尝试将显式返回类型添加到函数中,它将失败编译(隐式类型(通常有用的wile )会隐藏类似的错误)。
您可以返回Option[Config]类型( catch块返回None,以及返回Some(config)的正常处理),或者,如果希望保留异常信息,可以使用Either类型:
val clsCfg: Either[Config, Throwable] = try {
...
Left(config)
} catch { case e: OptionParserException => Right(e) }稍后您可以在以下几个方面进行匹配:
clsCfg match {
case Left(config) => // use your config here
case Right(exception) => // handle exception
}https://stackoverflow.com/questions/49785258
复制相似问题