Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala mutable.Map put/get句柄为null';是以一种意想不到的方式吗?_Scala - Fatal编程技术网

scala mutable.Map put/get句柄为null';是以一种意想不到的方式吗?

scala mutable.Map put/get句柄为null';是以一种意想不到的方式吗?,scala,Scala,我知道scala中不应该使用空值,但有时在与Java进行互操作时会出现这种情况。scala可变映射处理此问题的方式似乎不太合适: scala> import scala.collection.mutable import scala.collection.mutable scala> val m: mutable.Map[String, String] = mutable.Map.empty m: scala.collection.mutable.Map[String,String

我知道scala中不应该使用空值,但有时在与Java进行互操作时会出现这种情况。scala可变映射处理此问题的方式似乎不太合适:

scala> import scala.collection.mutable
import scala.collection.mutable

scala> val m: mutable.Map[String, String] = mutable.Map.empty
m: scala.collection.mutable.Map[String,String] = Map()

scala> m.put("Bogus", null)
res0: Option[String] = None

scala> m.get("Bogus")
res1: Option[String] = Some(null)

scala> m.getOrElse("Bogus", "default")
res2: String = null
在这种情况下,我希望
m.get
返回
None
。几乎像是一个bug,就像在代码的某个地方有一个
Some(v)
而不是
选项(v)


是否有关于更改此行为的讨论?

Null
String
的子类型:

scala> implicitly[Null <:< String]
res3: Null <:< String = <function1>
如果您想在映射中将
null
存储为
String
,这是您的权利


与Java的
Map#get
(我们称之为
javaLikeGet
)相比,Scala的
get
的行为大致如下:

def get(k: K) = if (containsKey(k)) { 
  Some(this.javaLikeGet(k)) 
} else { 
  None 
}
和你想象的不一样:

def get(k: K) = Option(this.javaLikeGet(k))
后一个版本(可能是您认为的)将为现有密钥获取
null
,将其传递到
选项(…)
,然后返回
None
。但是前一个版本(模拟实际实现的工作方式)会注意到键的存在,并将
javaLikeGet
返回的
null
包装成
Some

简单而一致的规则是:

如果键
k
存在,则
get(k)
返回
Some[V]
,否则返回
None

这比Java的
get
在两种完全不同的情况下返回
null
的奇怪行为要少得多



这是一个耗资数十亿美元的错误,但Scala不太可能修复它,因为它必须与Java进行互操作。我的猜测是,现在和将来都不会讨论改变这种行为,至少在整个编程环境发生根本性变化之前是这样。

Null
String
的子类型:

scala> implicitly[Null <:< String]
res3: Null <:< String = <function1>
如果您想在映射中将
null
存储为
String
,这是您的权利


与Java的
Map#get
(我们称之为
javaLikeGet
)相比,Scala的
get
的行为大致如下:

def get(k: K) = if (containsKey(k)) { 
  Some(this.javaLikeGet(k)) 
} else { 
  None 
}
和你想象的不一样:

def get(k: K) = Option(this.javaLikeGet(k))
后一个版本(可能是您认为的)将为现有密钥获取
null
,将其传递到
选项(…)
,然后返回
None
。但是前一个版本(模拟实际实现的工作方式)会注意到键的存在,并将
javaLikeGet
返回的
null
包装成
Some

简单而一致的规则是:

如果键
k
存在,则
get(k)
返回
Some[V]
,否则返回
None

这比Java的
get
在两种完全不同的情况下返回
null
的奇怪行为要少得多


这是一个耗资数十亿美元的错误,但Scala不太可能修复它,因为它必须与Java进行互操作。我的猜测是,现在和将来都不会讨论改变这种行为,至少在整个编程环境发生根本性变化之前不会讨论

在这种情况下,我本以为m.get不会返回任何值

为什么?
None
意味着键
“Bogus”
不在映射中,但您只需将其放入(值
null

Java的
Map
API在区分“此键的值为
null
”和“此键不在映射中”时存在问题,但Scala的不在映射中

在这种情况下,我本以为m.get不会返回任何值

为什么?
None
意味着键
“Bogus”
不在映射中,但您只需将其放入(值
null


Java的
Map
API在区分“此键的值为
null
”和“此键不在映射中”时存在问题,但Scala的不在映射中。我可以建议稍微澄清一下吗?与其说是
Map#get
方法在区分“value is null”和“key not in Map”方面存在问题,不如说是
Map#containsKey
总是工作得很好,所以对整个Map API的判断过于苛刻可能有点不公平,这只是
Map#get
有点奇怪。我也想到了这一点“例如,一些实现禁止空键和值”:)哦,是吗?抱歉,我没有意识到这一点不一致。那么,让我们把责任归咎于整个API:d之类的事情(如果实现支持空值,空返回还可以指示映射以前将空键与键关联。)“我可以建议你做一个小小的澄清吗?与其说是
Map#get
方法在区分“value is null”和“key not in Map”方面存在问题,不如说是
Map#containsKey
总是工作得很好,所以对整个Map API的判断过于苛刻可能有点不公平,这只是
Map#get
有点奇怪。我也想到了这一点“例如,一些实现禁止空键和值”:)哦,是吗?抱歉,我没有意识到这一点不一致。那么,让我们把责任归咎于整个API:d之类的事情(如果实现支持空值,空返回还可以指示映射以前将空键与键关联。)“我认为我的主要问题是,从语义上讲,scala已经设计了它的地图#变得像选项一样。令人惊讶的是,
Option(null)
返回
None
,但事实并非如此。@hiroprogator这样想:与Java的
get
(称之为
javaLikeGet
)相比,Scala的
get
类似于
def-get(k:k)=if(containsKey(k)){Some(this.likeget(k))}else{None}
而不是
def get(k:k)=Option(this.javaLikeGet(k))
。这样做就不那么令人惊讶了。而且它很有效,因为,例如,我对Sca