Scala-Spark - Try/Catch 正在改变案例类型 class
Scala-Spark - Try/Catch is changing type of case class
我正在尝试使用 sellmerfud.optparse 来解析用于启动 Spark2-Submit jar 文件的参数。我在下面粘贴的代码适用于粘贴到 spark2-shell 中,我在其中强制 args 值,因为它们将通过命令行传递。
问题是,当我使用 try/catch 时,我设置的变量没有分配给 class,但是当我不使用 try/catch 时,args 数组解析良好并且值可用我正在粘贴我在 spark2-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,我可以在其中轻松访问 class 成员。
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 来正确处理提交的格式错误的变量,但我不知道如何让它工作。感谢任何帮助。
可以在示例中说明发生了什么。基本上,当您使用 try
..catch
时,scala 将查看所有代码块的每个 return 类型(try
和所有 catch
,因为可能有多个)和 return 一种对所有这些都通用的类型。在您的情况下,它是 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-ish 的方式来处理它,你可以按照评论中的建议使用 Try()
monad,但你可以构建一个 returns Option[Config]
def buildConfig(args:Array[String]):Option[Config] = try {
Some(new OptionParser[Config] {
....
}.parse(args, Config())
} catch { _ => None }
请注意,try 和 catch return 都是 Option
,因为 Some()
和 None
都是 Option
。
然后使用模式匹配来确保处理成功
buildConfig(args) match {
case Some(conf) => // normal processing
case None => //
}
如另一个答案中所述,try
语句的 return 类型是 try
和所有 catch
块结果中的常见类型。您的 try
结果是 Config
,但是您的 catch
结果是 Unit
(因为它没有 return 任何值),它们的常见类型是Any
。您可以尝试向您的函数添加显式 return 类型,它会编译失败(隐式类型通常很有用,往往会隐藏这样的错误)。
您可以 return 一个 Option[Config]
类型(使用 catch
块 returning None
,以及正常处理 return ing Some(config)
), 或者,如果你想保留异常信息,你可以使用 Either
type:
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
}
我正在尝试使用 sellmerfud.optparse 来解析用于启动 Spark2-Submit jar 文件的参数。我在下面粘贴的代码适用于粘贴到 spark2-shell 中,我在其中强制 args 值,因为它们将通过命令行传递。
问题是,当我使用 try/catch 时,我设置的变量没有分配给 class,但是当我不使用 try/catch 时,args 数组解析良好并且值可用我正在粘贴我在 spark2-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,我可以在其中轻松访问 class 成员。
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 来正确处理提交的格式错误的变量,但我不知道如何让它工作。感谢任何帮助。
可以在示例中说明发生了什么。基本上,当您使用 try
..catch
时,scala 将查看所有代码块的每个 return 类型(try
和所有 catch
,因为可能有多个)和 return 一种对所有这些都通用的类型。在您的情况下,它是 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-ish 的方式来处理它,你可以按照评论中的建议使用 Try()
monad,但你可以构建一个 returns Option[Config]
def buildConfig(args:Array[String]):Option[Config] = try {
Some(new OptionParser[Config] {
....
}.parse(args, Config())
} catch { _ => None }
请注意,try 和 catch return 都是 Option
,因为 Some()
和 None
都是 Option
。
然后使用模式匹配来确保处理成功
buildConfig(args) match {
case Some(conf) => // normal processing
case None => //
}
如另一个答案中所述,try
语句的 return 类型是 try
和所有 catch
块结果中的常见类型。您的 try
结果是 Config
,但是您的 catch
结果是 Unit
(因为它没有 return 任何值),它们的常见类型是Any
。您可以尝试向您的函数添加显式 return 类型,它会编译失败(隐式类型通常很有用,往往会隐藏这样的错误)。
您可以 return 一个 Option[Config]
类型(使用 catch
块 returning None
,以及正常处理 return ing Some(config)
), 或者,如果你想保留异常信息,你可以使用 Either
type:
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
}