【问题标题】:Scala Option type in function parameter - Best Practices函数参数中的 Scala 选项类型 - 最佳实践
【发布时间】:2017-12-19 01:29:50
【问题描述】:

我很难理解 Scala Option, Some classes 的细微差别,希望你能帮助我。

据我从文档中了解到,当我们期望值是 A 类或 null 时,会使用 Option[A] 类型。虽然 Scala 中不存在 null 类型,但当我们与非缩放 API 对话时,可能会发生 null 场景。

示例 - 假设我有一个将字符串转换为整数值的函数

 def strToInt(s: String): Option[Int] = {

    val x: Option[Int] = try {
      Some(s.toInt)
    } catch {
      case e: Exception => None
    }

    x

  }

  def stringToInteger(s: String): Int = {

    Option(s) match {
        case None => 0
        case Some(s) => strToInt(s).getOrElse(0)
    }

}

这里我有一个包装函数“StringToInteger”,它检查函数的输入参数是字符串还是空值。如果为 null,则返回默认整数值 0,否则尝试使用 'strToInt' 函数将字符串转换为整数。

但是,当 stringToInteger 的输入参数为空时,我似乎遇到了以下错误。

stringToInteger(null)

错误:Null 类型的表达式不适合隐式转换

这是对 Option 习语的错误使用吗?

这是我遇到相同错误的另一个示例。在这种情况下,我只是检查输入的整数参数是否为空。

def isIntNull(i: Int): Boolean = {

     Option(i) match {
      case None => true
      case Some(i) => false
    }

  }

结果 -

isIntNull(123)
false

isIntNull(null)
Name: Unknown Error
Message: <console>:31: error: an expression of type Null is ineligible for implicit conversion
       isIntNull(null)

【问题讨论】:

  • 你使用的是什么版本的 Scala?
  • 您的第二个函数也可以重写,而无需手动将参数包装到选项中...def stringToInteger(s: String): Int = strToInt(s).getOrElse(0)
  • 您好,我使用的是 Scala 2.11。
  • 我在运行您的代码时没有遇到您的错误。你确定StringToInteger(上面有S)是你粘贴在这里的那个吗?

标签: scala user-defined-functions optional-parameters


【解决方案1】:

何时使用选项是一件简单的事情。如果一个方法试图访问一个合法不必存在的值,该方法应该返回一个选项。因此,从给定用户 ID 的数据库中获取用户的方法可以返回选项,但访问必要配置文件的函数不应返回选项。

【讨论】:

    【解决方案2】:

    在 scala 2.11 中将 NULL 传递给 Option(如 Option(null))存在问题,它会引发错误 - Null 类型的表达式不适合隐式转换

    但是2.12解决了(我在2.12.1测试过)

    【讨论】:

      【解决方案3】:

      这是因为 Scala 中的 Int 不可为空,它代表一个原语。 null 仅适用于引用类型(AnyRef 的子类型),不适用于基元(AnyVal 的子类型)。

      另外,更惯用:

      import scala.util.Try
      Try(s.toInt).toOption
      

      【讨论】:

      • 谢谢。您会说第一个示例 stringToInteger() 有效吗?我不确定为什么会抛出错误,因为输入参数是属于 AnyRef 的字符串。
      • @Yash 第一个例子是 not 对我抛出错误,这对我来说似乎是有效的。您确定要测试相同的代码吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      相关资源
      最近更新 更多