【问题标题】:Code runs with fastOptJS but fails with fullOptJS in Scala.js代码使用 fastOptJS 运行,但在 Scala.js 中使用 fullOptJS 失败
【发布时间】:2018-09-05 10:08:11
【问题描述】:

我在我的代码中遇到了由错误的 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


    【解决方案1】:

    在 Scala.js 中,与 Scala/JVM 不同,错误的强制转换不会可靠地抛出 ClassCastException。相反,错误转换是 未定义的行为,如 here 所指定。这意味着在fullOpt 中,程序可以任意行为,尤其是不允许在 throw 中。然而,在fastOpt 中,编译器是友好的并且可靠地抛出,但不是 ClassCastException(因为它会给人一种虚假的安全感),而是UndefinedBehaviorError

    UndefinedBehaviorErrors 绝对不能被捕获,因为捕获一个隐藏了一个错误,该错误在 fullOpt 中显示。这是您的错误:您在case _: Throwable => 下捕获了UndefinedBehaviorError。请注意catching Throwable is bad practice in Scala。相反,您应该使用case scala.util.control.NonFatal(_) =>NonFatal 处理程序不会捕获UndefinedBehaviorError,因此不会隐藏错误。

    现在解决您的问题,您根本不使用asInstanceOf 作为类型测试的手段。即使在 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()
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 2017-03-18
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      相关资源
      最近更新 更多