为什么有些(null)不被视为无?

时间:2011-04-26 21:21:30

标签: scala null option

我很好奇:

scala> Some(null) == None
res10: Boolean = false

为什么Some(null)没有转化为None

6 个答案:

答案 0 :(得分:55)

您应该使用Option(null)达到所需效果并返回None

Some(null)只是创建一个新的Option,其中包含一个定义的值(因此Some),实际上是null,并且几乎没有合理的理由来创建这样的{{1}}在实际代码中。

答案 1 :(得分:27)

不幸的是,null是任何AnyRef类型的有效值 - 这是Scala与Java互操作的结果。因此,采用类型为A的对象并在内部将其存储在Option内的方法可能需要在该选项中存储null

例如,假设您有一个方法,它接受列表的头部,检查该头部是否与商店中的键对应,然后返回true(如果是)。有人可能会这样实现它:

def isFirstAcceptable(list: List[String], keys: Set[String]): Boolean =
    list.headOption map keys getOrElse false

所以,这就是......如果listkeys里面的内容来自某些Java API,它们都可能包含null!如果无法Some(null),那么isFirstAcceptable(List[String](null), Set[String](null))将返回false而不是true

答案 2 :(得分:12)

Scala的大部分WTF可归因于它与Java兼容的需求。 null通常在Java中用作值,表示可能缺少值。例如,如果密钥不匹配,hashMap.get(key)将返回null

考虑到这一点,请考虑在Option中包装null返回方法的以下可能值:

if (b) Some(hashMap.get(key)) else None
// becomes -->
None // the method was not invoked;
Some(value) // the method was invoked and a value returned; or
Some(null) // the method was invoked and null was returned.
在这种情况下,

Some(null)似乎与None完全不同,以保证在语言中允许它。

当然,如果您的情况不适合,那么只需使用:

if (b) Option(hashMap.get(key)) else None
// becomes -->
None // the method was not invoked or the mapped value was null; or
Some(value) // the method was invoked and a value returned

答案 3 :(得分:12)

我认为线程中的其他人可以很好地解释为什么Some(null)“应该”存在,但是如果你恰好在某个地方获得Some(null)并希望快速将其转换为{{ 1}},我之前做过这个:

None

当起始scala> val x: Option[String] = Some(null) x: Option[String] = Some(null) scala> x.flatMap(Option(_)) res8: Option[String] = None 是一个合法的非空值时,事情就像你想要的那样起作用:

Option

答案 4 :(得分:2)

作为一个简单的思想实验,考虑两个字符串列表,一个长度为5,另一个长度为20。

因为我们在JVM上运行,所以可以将null作为有效元素插入到其中一个列表中 - 所以将它作为元素#10放在长列表中

那么,差异在于以下两个表达式返回的值是什么?

编辑:get交换lift,我在想地图......

shortList.lift(10) //this element doesn't exist
longList.lift(10)  //this element exists, and contains null

答案 5 :(得分:0)

因为Option被认为是Functor并且是Functor意味着:

  1. 在Scala中具有Sub Torrent_data() Dim http As New XMLHTTP60, html As New HTMLDocument Dim movie_name As Object, movie As Object With http .Open "GET", "https://www.yify-torrent.org/search/1080p/", False .send html.body.innerHTML = .responseText End With Set movie_name = html.querySelectorAll("div.mv h3 a") Dim i As Integer For i = 0 To movie_name.Length - 1 Cells(x + i, 1) = movie_name(i).innerText Next i End Sub 功能(unit或仅apply
  2. 具有Option("blah")功能,可以转换map但不转换上下文
  3. 的值
  4. Obeys 2 Functor法 - 身份法和联想法
  5. 在本主题中,主要部分是#2 - T=>B无法转换上下文。 Option(1).map(t=>null)应保留。否则它会制动联想法!

    请考虑以下法律示例:

    Some

    但如果def identity[T](v: T) = v def f1(v: String) = v.toUpperCase def f2(v: String) = v + v def fNull(v: String): String = null val opt = Option("hello") //identity law opt.map(identity) == opt //Some(hello) == Some(hello) //associative law opt.map(f1 _ andThen f2) == opt.map(f1).map(f2) //Some(HELLOHELLO) == Some(HELLOHELLO) opt.map(fNull _ andThen f2) == opt.map(fNull).map(f2) //Some(nullnull) == Some(nullnull) 生成Option("hello").map(t=>null)怎么办?联想法将被打破:

    None

    这是我的想法,可能是错的