Scala 为什么用一种更高的类型来表现一种特质是行不通的?
有人能给我解释一下,为什么下面的代码不起作用,我该怎么做才能使它起作用 Scala版本是2.10.4Scala 为什么用一种更高的类型来表现一种特质是行不通的?,scala,Scala,有人能给我解释一下,为什么下面的代码不起作用,我该怎么做才能使它起作用 Scala版本是2.10.4 scala> trait A[T[_]] defined trait A scala> trait B[T] defined trait B scala> manifest[A[B]] <console>:10: error: erroneous or inaccessible type manifest[A[B]] scala>trait A[T[\u]]
scala> trait A[T[_]]
defined trait A
scala> trait B[T]
defined trait B
scala> manifest[A[B]]
<console>:10: error: erroneous or inaccessible type
manifest[A[B]]
scala>trait A[T[\u]]
定义特征A
scala>性状B[T]
定义性状B
scala>清单[A[B]]
:10:错误:错误或无法访问的类型
舱单[A[B]]
清单
有很多限制,因此它被弃用,取而代之的是类型标签
import scala.reflect.runtime.universe.TypeTag
trait A[T[_]]
trait B[T]
typeTag[A[B]] // reflect.runtime.universe.TypeTag[A[B]] = TypeTag[A[B]]
这就是说,如果您仍然希望使用
清单
,则必须使用它的弱表类清单
,因为它可以表示更高阶的种类,因为它不需要指定完整的类型信息
所以你应该能做到
classManifest[A[B]]
对吧??嗯,不完全是。这是Scala 2.11.2中的错误
类型参数(B)的类型不符合类型参数(T类型)的预期类型。B的类型参数与T类型的预期参数不匹配:
特征B有一个类型参数,但类型T没有
编译器正在变得混乱,因为B
似乎没有正确的“形状”。嗯,好的,斯卡拉克,相信我,它的形状真的很合适。让我们用勺子喂你
classManifest[A[({type l[T] = B[T]})#l]]
// ClassManifest[A[[T]B[T]]] = A[<?>]
classManifest[A[({type l[T]=B[T]})#l]]
//类清单[A[[T]B[T]]=A[]
这就是scalac在不同更高种类之间的破类型推断,它非常出色。TypeTag在这种情况下当然可以工作,但数组是很棘手的。您是否知道如何检测捕获的参数是否为数组?具体来说:
typeTag[A[Array]].tpe.asInstanceOf[TypeRefApi].args.head