スカラ2.10を使用していて、ジェネリックパラメータの型推論を使用するときに私が奇妙な振る舞いをすることがわかりました。 (i
に注意してくださいだけでダミー変数である)以下の例を考えてみましょう:スカラジェネリック型の推論が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)
関数内print文が推測されClassTag
と一致するには、一貫性のあると思われます。
ただし、2番目の文は、ClassTag
のコンパイラが推論する内容と、関数内に出力される内容と実際の戻り値の種類との間に矛盾があります。
コンパイラがという型宣言からClassTag
を推測することが予想されます。これは間違っていますか?誰かが私を啓発することはできますか?
ここではいくつかのコードでコレクションをフィルタリングするために実際にclasstagを使用しています(具体的にはと比較してT
を明示的に指定しないと失敗します)。
私は実際に共分散であり、この問題にぶつかるrx Observablesを使用していました。私は 'collect'ステートメントでClassTagを使用して特定のタイプのアイテムのみを取り出しました。 'observable collect {case t:T => t}'という引数を渡す値はありません。あなたが言うように、推論の問題を修正しました。ご意見をいただきありがとうございます。 – Luciano
このような状況でもタイプシグネチャを収集する可能性のあるマクロソリューションがありますが、ここでマクロを使用するのは難しいと思います。変数型を省略し、明示的に '[T]'を指定してください。 – Maxim