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ます。型注釈を追加すると、: Any再びx印刷nullされます。

同じタイプの引数がそこで起こっていることprintlnを期待しているので、私は推測しています。Any

より一般的な型の変数に式を代入すると、その式の値が変わる可能性があるのはどうしてですか? 私はそれが本当に直観に反していると思います。

ボクシングと何か関係があるので、実際には2つの異なる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 に答える