Eya*_*oth 4 reflection scala compiler-warnings
我有两个非常相似的方法.唯一的区别是使用ClassTag和TypeTag:
def matchClass[A: ClassTag](v: Any) =
v match {
case a: A => "it's A"
case _ => "not A"
}
def matchType[A: TypeTag](v: Any) = ... // same code as matchClass
Run Code Online (Sandbox Code Playgroud)
将显示编译警告matchType,但不会显示matchClass:
abstract type pattern A is unchecked since it is eliminated by erasure case a: A
为什么会有警告?为什么它只显示TypeTag和不显示ClassTag?
您没有看到警告,classTag因为该检查仅适用于那些:
scala> matchClass[Int]("aaa")
res82: String = not A
scala> matchClass[Int](5)
res83: String = it's A
Run Code Online (Sandbox Code Playgroud)
并不适用于typeTag:
scala> matchType[Int](5)
res84: String = it's A
scala> matchType[Int]("aaa")
res85: String = it's A
Run Code Online (Sandbox Code Playgroud)
原因是对于classTags上的模式匹配(当它看到一个隐式时),编译器生成如下内容:
case a: A if classTag[A].runtimeClass.isInstance(a) => ...
Run Code Online (Sandbox Code Playgroud)
有没有办法让runtimeClass对TypeTag一般的S(同时考虑编译和运行时,看到更新的特定情况下,允许提取其仅在运行时),所以这就是为什么编译器不改造他们.默认情况下,由于擦除,模式匹配在泛型(多态)类型上无法匹配,因此默认情况下您可以看到该警告:
scala> def matchGeneric[A](v: Any) =
| v match {
| case a: A => "it's A"
| case _ => "not A"
| }
<console>:28: warning: abstract type pattern A is unchecked since it is eliminated by erasure
case a: A => "it's A"
^
matchGeneric: [A](v: Any)String
Run Code Online (Sandbox Code Playgroud)
更新:正如@Seth Tisue提到的,当标签来自运行时Universe(仅)时,您可以获得它的运行时类(但您必须首先创建一个镜像).
参考:
按照scaladocs的ClassTag本身:
编译器试图通过缠绕一个把未经检查的类型测试在模式匹配到检查那些
(_: T)类型图案ct(_: T),其中ct是ClassTag[T]实例.在调用其他提取器之前必须进行类型测试.如果in 是不可检查的,SomeExtractor(...)则变成了,但我们有一个实例.ct(SomeExtractor(...))TSomeExtractor.unapply(x: T)ClassTag[T]
TypeTag scaladocs和语言规范本身没有提到任何这样的功能 TypeTags
推测性解释
没有办法确定为什么某些功能是否被实现,所以任何推测都是固执的(并且超出SO范围,甚至不直接与您的问题相关,而是回答@Tom的评论).尽管如此(截至2.12)......
这可能是因为"ClassTags仅提供对类型的运行时类的访问"并且是scala-library的一部分(即使它们的包是scala.reflect.),而TypeTags是单独(并且相当广泛)的反射API的一部分,因此是指编译或运行时间取决于universe它们的位置,因此为那些编写额外的检查(在综合期间!!)不仅会混淆(对于用户而言),而且对语言开发人员来说也很难:合成本身就是在一个不同的(编译器)模块中,[synthesis]不依赖于反射(只有scala-library),因为模式匹配合成正在早期的"patmat"阶段发生.此外,scala spec(12.3.4.2 Variance)提到了ClassTag的使用,用于数组实例的合成调整(非常推测性地)可能意味着ClassTag与"syntax sugar"特征更加集成.
| 归档时间: |
|
| 查看次数: |
2857 次 |
| 最近记录: |