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

Geo*_*Geo 36 null scala option

我好奇:

scala> Some(null) == None
res10: Boolean = false
Run Code Online (Sandbox Code Playgroud)

为什么不Some(null)转变为None

Jea*_*let 57

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

Some(null)只是创建一个Option带有定义值的new (因此Some)实际上null,并且在实际代码中创建一个这样的函数的原因很少.


Dan*_*ral 27

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

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

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

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

  • +1好的用例为什么`Some(null)`应该存在! (2认同)
  • @Jean-PhilippePellet 可以说“null”根本不应该存在于 Scala 中,并且每个 Java 到 Scala 的接口都需要将 Java 类型包装在“Option”中。(这实际上是一些没有“null”的语言(例如 Rust)提供与具有“null”的语言互操作的方式。) (2认同)

ove*_*ink 13

我认为线程中的其他人能够很好地解释为什么Some(null)"应该"存在,但是如果你碰巧遇到Some(null)某个地方并想要快速转变它None,我之前已经做过:

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

scala> x.flatMap(Option(_))
res8: Option[String] = None
Run Code Online (Sandbox Code Playgroud)

当起始Option是一个合法的非空值时,事情就像你可能想要的那样:

scala> val y: Option[String] = Some("asdf")
y: Option[String] = Some(asdf)

scala> y.flatMap(Option(_))
res9: Option[String] = Some(asdf)
Run Code Online (Sandbox Code Playgroud)


Syn*_*sso 12

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

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

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.
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)