我试图模仿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
)?如果是的话,有没有办法避免这种情况?
答案 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