加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 构造Option对象的正确方法:Option(value)vs Some(valu

发布时间:2020-12-16 19:10:55 所属栏目:安全 来源:网络整理
导读:启动Option对象的两种方法的优缺点是什么: 1. def getAmount: Option[Int] = { val a: Int = 1 Option(a)} 2. def getAmount: Option[Int] = { val a: Int = 1 Some(a)} 我应该使用哪个? 解决方法 有两个重要的区别.首先,如果参数为null,则Option将返回Non
启动Option对象的两种方法的优缺点是什么:

1.

def getAmount: Option[Int] = {
  val a: Int = 1
  Option(a)
}

2.

def getAmount: Option[Int] = {
  val a: Int = 1
  Some(a)
}

我应该使用哪个?

解决方法

有两个重要的区别.首先,如果参数为null,则Option将返回None:

scala> val x: Option[String] = Some(null)
x: Option[String] = Some(null)

scala> val y: Option[String] = Option(null)
y: Option[String] = None

这可能很有用,但并不总是你想要的,并且(同样重要的是)它表明在某些情况下参数可能为空的合理机会,这可能会产生误导.

有些更适合于您希望围绕您知道不为null的值生成Option的情况.不幸的是,第二个区别是Some(foo)的返回类型是Some [Whatever],而不是Option [Whatever],这在某些情况下非常不方便,因为有些推断意味着当你尝试使用时会出现类型错误之后某些位置无或选项.在这些情况下,你必须使用Some(foo):Option [Whatever],这是非常不愉快的.

例如,假设我们有一个表示(我们希望)整数的字符串列表,我们想要解析它们并对它们求和.如果有解析错误,我们想要一个None,否则我想要一些(总计).以下是使用标准库在单次遍历中执行此操作的相当合理的方法:

List("1","2","3").foldLeft(Some(0)) {
  case (acc,item) => for {
    t <- acc
    n <- util.Try(item.toInt).toOption
  } yield t + n
}

除了这不起作用 – 我们得到一个类型错误:

<console>:10: error: type mismatch;
 found   : Option[Int]
 required: Some[Int]
                  t <- acc
                    ^

我们可以通过编写.foldLeft(Some(0):Option [Int])来解决这个问题,但是呃.

这在您的具体示例中不是问题,因为返回类型是显式Option [Int],因此您不必担心类型推断.在这种情况下,某些(a)是正确的选择.

作为旁注,Scalaz提供了一些和没有构造函数来帮助您避免类型推断问题和像Some(foo)这样的嘈杂解决方案:Option [Whatever]:

scala> import scalaz._,Scalaz._
import scalaz._
import Scalaz._

scala> some(10)
res0: Option[Int] = Some(10)

scala> none[Int]
res1: Option[Int] = None

两种返回类型都是Option,这使得类型推断变得更加容易.如果您不想使用Scalaz,您可以自己轻松定义这些:

scala> def some[A](a: A): Option[A] = Some(a)
some: [A](a: A)Option[A]

scala> def none[A]: Option[A] = None
none: [A]=> Option[A]

如果您使用这些而不是Some和None,您永远不必担心推断出不恰当的特定类型.

总结一下:仅在参数可能为null的情况下使用Option(foo)(理想情况下,应该只用于与Java的互操作性).在值已明确键入Option的情况下使用Some(foo).如果推断的类型将是Some [Whatever],请添加:Option [Whatever]类型注释,或者使用类似Scalaz的类型.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读