为什么表达式的值取决于它赋给的变量?

时间:2013-05-08 08:41:37

标签: scala type-inference

我试图模仿C#的default关键字:

private class Default[T] {
    private var default : T = _
    def get = default
}

然后在包对象中定义:

def default[T] = new Default[T].get

我希望default[Int]0,但

println(default[String])
println(default[Int])
println(default[Double])
println(default[Boolean])

全部打印null。然而

val x = default[Int]
println(x)

打印0。如果我向: Any添加类型注释x,则会再次打印null

我猜是因为println期望Any类型的参数在那里发生同样的事情。

如何将表达式赋值给更通用类型的变量,是否可以更改该表达式的值?我发现这非常违反直觉。

它是否与拳击有关,所以我实际上调用了两个不同的default函数(一次使用原始int,一次使用Integer)?如果是的话,有没有办法避免这种情况?

2 个答案:

答案 0 :(得分:2)

在研究了生成的字节码后,我意识到实际发生了什么。 default[T] 始终会返回null,但会将其分配给基元调用BoxesRunTime.unboxTo...,将null转换为原始默认值。

答案 1 :(得分:1)

没有那么多这样的课程。您可以明确地处理所有这些:

import scala.reflect.ClassTag

def default[T: ClassTag]: T = (implicitly[ClassTag[T]] match {
  case ClassTag.Boolean => false
  case ClassTag.Byte => 0: Byte
  case ClassTag.Char => 0: Char
  case ClassTag.Double => 0: Double
  case ClassTag.Float => 0: Float
  case ClassTag.Int => 0: Int
  case ClassTag.Long => 0: Long
  case ClassTag.Short => 0: Short
  case ClassTag.Unit => ()
  case _ => null.asInstanceOf[T]
}).asInstanceOf[T]

scala> println(default[Int])
0