5

我有一个采用 2 个参数的 Scala 方法:

def test(x:Long,y:Int){}

在某些情况下,我需要传递 null 而不是 long ...类似的东西:

test(null,x)

结果:

scala> test(null,2) :7: 错误:类型不匹配;发现:空(空)需要:长测试(空,2)

为什么我需要传递null?实际上,由于某种原因,我无法传递任何默认值。因此,我需要这样一个空值。

*注意: *我知道解决方案将使其成为选项。但是,假设我无法控制此方法签名,我可以做任何工作吗?

有任何想法吗!

谢谢。

4

3 回答 3

8

Null 是继承自 AnyRef 的类型的子类型,而不是继承自 AnyVal 的值类型。这就是您无法传入 null 的原因。这对应于在 java 中您不能拥有 long 类型的 null。(忽略盒装的 Long 类型)。

但是,这表明方法的签名应更改为:

def test(x: Option[Long], y: Int)

这表明有时它对 x 没有价值。由于我们有一个很好的 Option 类来处理这个实例,所以几乎没有使用空值的正当理由,您需要依赖开发人员记住检查空值。相反,使用 Option,编译器将强制您处理该值可能不存在的事实。

于 2012-11-30T02:00:36.460 回答
3

由于您无法更改签名,因此请考虑Thinking Option[Foo] 的错误是表达缺失函数参数的唯一/最自然的方式

如果你的函数的参数是一个下限,那么 Long.MinValue 可能是一个自然的默认值。

如果通过“出于某种原因,我无法传递任何默认值”(无论这可能意味着什么),您的意思是您无法将默认值添加到签名中,并且您将采用另一个调整方法的答案中建议的路线,您不妨在转发之前将 f(a,b) 更改为 g(b, a=Long.MinValue) 或其他任何内容。

不要让适配器方法的客户端调用 g(b, None),而是让它们调用 g(b)。无论如何,您都没有将 Option 传递给底层 f(a,b) 。

于 2012-11-30T03:36:53.460 回答
0

将 scala 原语转换为 Java 包装器类的方法是使用 Java Primitive 包装器上的静态 valueOf 成员。我遇到了这个问题,我需要将 Option[Double] 转换为 java.lang.Double 或 null。这就是我所做的:

val value: Option[Double]
val orNull = value.map(java.lang.Double.valueOf(_)).orNull

如果您正在调用接受 java.lang.Long/Double/Integer 的方法,则只需传递文字 null 即可

于 2017-02-24T12:19:11.973 回答