我正在使用Scala 2.10,並且發現在使用泛型參數的類型推斷時我認爲是奇怪的行爲。考慮下面的例子(注意i
僅僅是一個虛擬變量):Scala通用類型推斷與ClassTag不一致
scala> import scala.reflect.{ClassTag,classTag}
|
| def broken[T : ClassTag](i : Int) : List[T] = {
| println("ClassTag is : " + classTag[T])
| List.empty[T]
| }
import scala.reflect.{ClassTag, classTag}
broken: [T](i: Int)(implicit evidence$1: scala.reflect.ClassTag[T])List[T]
scala> broken(3)
ClassTag is : Nothing
res0: List[Nothing] = List()
scala> val brokenVal : List[String] = broken(3)
ClassTag is : Nothing
brokenVal: List[String] = List()
呼叫broken(3)
似乎一致,在打印語句中的功能與推斷ClassTag
同意。
但是,第二種說法是,編譯器推斷ClassTag
,並在函數內部打印的內容與實際返回類型是什麼不一致。
我本來希望編譯器能從類型聲明中推出ClassTag
,即List[String]
。這是不正確的?有人可以啓發我嗎?
這裏的某些其它方面:我實際使用classtag在一些代碼(這裏沒有顯示)來篩選集合,這顯然失敗的時候我不指定T
明確,因爲它是比較反對Nothing
類型。
我實際上使用rx Observables,它也是協變的,並且遇到了這個問題。我在'collect'語句中使用ClassTag只拾取某種類型的項目。因爲我使用類型本身來過濾東西,即'observable collect {case t:T => t}',所以沒有任何價值可以作爲參數傳入,像你說的那樣可以解決推理問題。感謝您的反饋意見。 – Luciano
即使在這種情況下,仍然有可能收集類型簽名的宏解決方案,但我認爲在這裏使用宏是矯枉過正的。只需省略變量類型並明確指定'[T]'。 – Maxim