首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Scala-火花-尝试/捕捉正在改变case类的类型

Scala-火花-尝试/捕捉正在改变case类的类型
EN

Stack Overflow用户
提问于 2018-04-11 22:24:17
回答 2查看 179关注 0票数 2

我试图使用sellmerfud.optparse来解析用于启动Spark2 2-Submit jar文件的参数。下面粘贴的代码适合粘贴到闪烁2-shell中,在那里我强制使用args值,因为它们将通过命令行传递。

问题是,当我使用正在设置的try/catch变量时,没有分配给类,但是当我不使用try/catch时,args数组解析得很好,并且值是可用的,我正在粘贴我在闪烁2-shell会话中捕获的内容,以提供信息以查看发生了什么。

代码语言:javascript
运行
复制
  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)

从上述代码输出的行:

代码语言:javascript
运行
复制
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行时,如下所示:

代码语言:javascript
运行
复制
  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,在这里我可以轻松地访问类成员。

代码语言:javascript
运行
复制
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来正确地处理提交的格式错误的变量,但我不知道如何工作。任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-12 00:39:07

正在发生的事情可以在一个例子中显示出来。基本上,当您使用try.catch时,scala将查看所有代码块(try和所有catch,因为可能有多个)的每种返回类型,并返回所有代码块共有的一个类型。在你的例子中,它是Any。示例:

代码语言:javascript
运行
复制
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]的函数。

代码语言:javascript
运行
复制
def buildConfig(args:Array[String]):Option[Config] = try { 
 Some(new OptionParser[Config] {
  ....
  }.parse(args, Config())
} catch { _ => None }   

请注意,由于OptionNone都是Option,所以尝试并捕获都返回一个Option。然后使用模式匹配确保处理成功。

代码语言:javascript
运行
复制
buildConfig(args) match {
     case Some(conf) => // normal processing
     case None => //
}
票数 3
EN

Stack Overflow用户

发布于 2018-04-12 14:07:57

正如在另一个答案中提到的,try语句的返回类型是try和所有catch块结果中的常见类型。您的try会产生一个Config,但是您的catch会生成一个Unit (因为它不返回任何值),它们的常见类型是Any。您可以尝试将显式返回类型添加到函数中,它将失败编译(隐式类型(通常有用的wile )会隐藏类似的错误)。

您可以返回Option[Config]类型( catch块返回None,以及返回Some(config)的正常处理),或者,如果希望保留异常信息,可以使用Either类型:

代码语言:javascript
运行
复制
val clsCfg: Either[Config, Throwable] = try {
  ...
  Left(config)
} catch  { case e: OptionParserException => Right(e) }

稍后您可以在以下几个方面进行匹配:

代码语言:javascript
运行
复制
clsCfg match {
  case Left(config) => // use your config here
  case Right(exception) => // handle exception
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49785258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档