2013-05-08 45 views
2

我試圖immitate的default關鍵字的C#:爲什麼表達式的值取決於分配給它的變量?

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)?如果是,有沒有辦法避免這種情況?

+0

'def default [T]:T = null.asInstanceOf [T]'更短。 – senia 2013-05-08 08:50:17

+0

有趣的是,嘗試'私有val默認值:T = _'會產生錯誤:未綁定的佔位符參數。 – 2013-05-08 08:50:47

+0

@senia:對於'Boolean',不會總是'null'而不是'0',例如'Int'或'false'? – 2013-05-08 08:51:41

回答

2

研究生成的字節碼後,我意識到實際發生了什麼。 default[T]總是返回null,但將其分配給原始調用BoxesRunTime.unboxTo...null轉換爲任何原始默認值。

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 
+0

是的,這是實現'default'的一種方式,謝謝。儘管我的代碼失敗,但我更感興趣。 – 2013-05-08 09:04:38

相關問題