代码使用 fastOptJS 运行,但在 Scala.js 中使用 fullOptJS 失败
Code runs with fastOptJS but fails with fullOptJS in Scala.js
我在我的代码中捕获了错误的 asInstanceOf 引发的 UndefinedBehaviorError,如下所示:
$("button").on(
"click",
".showDialog",
(event: JQueryEventObject) => {
event.preventDefault()
val helpText = "Enter any number"
js.Dynamic.global.swal(
JC(
title = helpText,
text = helpText,
`type` = "input",
showCancelButton = true,
closeOnConfirm = false,
inputPlaceholder = helpText
),
(input: Any) => {
try {
input.asInstanceOf[Boolean]
} catch {
case _: Throwable =>
try {
val correctInput = input.asInstanceOf[String].toDouble
global.console.log("success")
} catch {
case _: Throwable =>
js.Dynamic.global.swal.showInputError("Incorrect data!")
}
}
}
)
}
)
它在 fastOptJS 上运行良好,但在 fullOptJS 上运行失败。如何使用 fullOptJS 或其他选项将此代码正确重写为 运行?
在 Scala.js 中,错误的转换不会可靠地抛出 ClassCastException
,这与 Scala/JVM 不同。相反,错误的转换是 未定义的行为 ,如指定的 here。这意味着在 fullOpt
中,程序可以任意行为,特别是不允许抛出。然而,在 fastOpt
中,编译器是友好的并且可靠地抛出,但是 不是 一个 ClassCastException
(因为它会给人一种错误的安全感),而是一个 UndefinedBehaviorError
.
UndefinedBehaviorError
绝不能被捕获,因为捕获一个 隐藏了一个错误 , 将 在 fullOpt 中浮出水面。这是你的错误:你在 case _: Throwable =>
下捕获了 UndefinedBehaviorError
。请注意 catching Throwable
is bad practice in Scala。相反,您应该使用 case scala.util.control.NonFatal(_) =>
。 NonFatal
处理程序 不会 捕获 UndefinedBehaviorError
,因此不会隐藏错误。
现在要解决你的问题,你根本不需要使用asInstanceOf
作为type-test的手段。即使在 Scala/JVM 上,该代码也是非常糟糕的做法。改为使用模式匹配:
(input: Any) => {
def reportIncorrectData(): Unit =
js.Dynamic.global.swal.showInputError("Incorrect data!")
input match {
case input: Boolean =>
// Here, input is a Boolean
input
case input: String =>
// Here, it is a String; let's try to convert it to Double
try {
val correctInput = input.toDouble
} catch {
case _: NumberFormatException =>
reportIncorrectData()
}
case _ =>
// It is something else, always incorrect data
reportIncorrectData()
}
}
我在我的代码中捕获了错误的 asInstanceOf 引发的 UndefinedBehaviorError,如下所示:
$("button").on(
"click",
".showDialog",
(event: JQueryEventObject) => {
event.preventDefault()
val helpText = "Enter any number"
js.Dynamic.global.swal(
JC(
title = helpText,
text = helpText,
`type` = "input",
showCancelButton = true,
closeOnConfirm = false,
inputPlaceholder = helpText
),
(input: Any) => {
try {
input.asInstanceOf[Boolean]
} catch {
case _: Throwable =>
try {
val correctInput = input.asInstanceOf[String].toDouble
global.console.log("success")
} catch {
case _: Throwable =>
js.Dynamic.global.swal.showInputError("Incorrect data!")
}
}
}
)
}
)
它在 fastOptJS 上运行良好,但在 fullOptJS 上运行失败。如何使用 fullOptJS 或其他选项将此代码正确重写为 运行?
在 Scala.js 中,错误的转换不会可靠地抛出 ClassCastException
,这与 Scala/JVM 不同。相反,错误的转换是 未定义的行为 ,如指定的 here。这意味着在 fullOpt
中,程序可以任意行为,特别是不允许抛出。然而,在 fastOpt
中,编译器是友好的并且可靠地抛出,但是 不是 一个 ClassCastException
(因为它会给人一种错误的安全感),而是一个 UndefinedBehaviorError
.
UndefinedBehaviorError
绝不能被捕获,因为捕获一个 隐藏了一个错误 , 将 在 fullOpt 中浮出水面。这是你的错误:你在 case _: Throwable =>
下捕获了 UndefinedBehaviorError
。请注意 catching Throwable
is bad practice in Scala。相反,您应该使用 case scala.util.control.NonFatal(_) =>
。 NonFatal
处理程序 不会 捕获 UndefinedBehaviorError
,因此不会隐藏错误。
现在要解决你的问题,你根本不需要使用asInstanceOf
作为type-test的手段。即使在 Scala/JVM 上,该代码也是非常糟糕的做法。改为使用模式匹配:
(input: Any) => {
def reportIncorrectData(): Unit =
js.Dynamic.global.swal.showInputError("Incorrect data!")
input match {
case input: Boolean =>
// Here, input is a Boolean
input
case input: String =>
// Here, it is a String; let's try to convert it to Double
try {
val correctInput = input.toDouble
} catch {
case _: NumberFormatException =>
reportIncorrectData()
}
case _ =>
// It is something else, always incorrect data
reportIncorrectData()
}
}