我很好奇:
scala> Some(null) == None
res10: Boolean = false
为什么Some(null)
没有转化为None
?
答案 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
所以,这就是......如果list
和keys
里面的内容来自某些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意味着:
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
)Option("blah")
功能,可以转换map
但不转换上下文在本主题中,主要部分是#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
这是我的想法,可能是错的