2015-10-05 42 views
3

我在爲具有類型成員的類型解析scala.reflect.Manifest時遇到問題。爲類型成員的類型解析`Manifest`

例如,

import scala.reflect.Manifest 

trait Foo { 
    type T 
} 

trait Bar[T] 

object Main extends App { 

    val barM: Manifest[Bar[Int]] = 
    implicitly[Manifest[Bar[Int]]] 

    val fooM: Manifest[Foo{type T = Int}] = 
    implicitly[Manifest[Foo{type T = Int}]] 

} 

上面的代碼不編譯,給出下面的錯誤。

Foo.scala:15: error: type mismatch; 
found : scala.reflect.Manifest[Foo] 
required: scala.reflect.Manifest[Foo{type T = Int}] 
Note: Foo >: Foo{type T = Int}, but trait Manifest is invariant in type T. 
You may wish to investigate a wildcard type such as `_ >: Foo{type T = Int}`. (SLS 3.2.10) 
    implicitly[Manifest[Foo{type T = Int}]] 
      ^
one error found 

barM聲明工作得很好。

我知道類型成員不是類型參數,但我絕對沒有注意到所有的細節。

如何才能解決Manifest類型的混凝土類型成員?

+0

看起來它可能與此相關,http://www.scala-lang.org/old/node/6550。 – isomarcte

回答

1

結構類型不受Manifest支持。 SI-4252Manifest結構類型)被標記爲「不會修復」,建議您使用TypeTag代替。 Manifest也很快就會被棄用。

scala> import scala.reflect.runtime.universe.TypeTag 
import scala.reflect.runtime.universe.TypeTag 

scala> implicitly[TypeTag[Foo { type T = Int} ]] 
res18: reflect.runtime.universe.TypeTag[Foo{type T = Int}] = TypeTag[Foo{type T = Int}] 

你也可以用類型別名來解決這個問題,但是如果沒有用例就很難說。

scala> type FooAux[T] = Foo { type T } 
defined type alias FooAux 

// Compiles, but is it useful? 
scala> implicitly[Manifest[FooAux[Int]]] 
res19: scala.reflect.Manifest[FooAux[Int]] = Foo 
+0

我以爲你的回答是正確的,但現在我不確定。這*不是結構類型。雖然語法相似,但結構類型會發出反射調用來驗證某些內容是否正確,而這只是普通的舊類型成員,沒有反射調用。 – isomarcte

+0

我已經嘗試過類型別名解決方案。唉,它不起作用,因爲編譯器仍然對類型成員的變化感到不安。 – isomarcte