2

我试图模仿defaultC#的关键字:

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。如果我添加类型注释: Anyx它会再次打印null

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

将表达式分配给更通用类型的变量怎么可能改变该表达式的值?我觉得这真的违反直觉。

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

4

2 回答 2

2

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

于 2013-05-08T08:57:00.047 回答
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
于 2013-05-08T09:02:30.947 回答