如果与ClassTag一起使用,模式匹配会选择错误的大小写

巴默巴赫

方差和ClassTags之间有什么联系TypeTags

我有两种类型,T1T2,用作类型参数。

case class T1()
case class T2()

我有一个带有不变类型参数和一个子类的抽象类,如果我想检查类型参数的类型,则只有在模式中没有类型检查时才起作用,只是在后卫中。如果存在类型测试,它将始终选择第一种情况。

类型检查是必需的,因为在我的真实代码中,我想为每种类型调用不同的函数。有单独的功能In[T1]In[T2]

abstract class In[T]
case class VIn[T]() extends In[T]

def test1[T:ClassTag](v:In[T]) = v match {
  case x : VIn[T1@unchecked] if classTag[T] == classTag[T1] => "T1"
  case y : VIn[T2@unchecked] if classTag[T] == classTag[T2] => "T2"
}
test1(VIn[T1]())  //T1
test1(VIn[T2]())  //T1 !!!

def test2[T:ClassTag](v:In[T]) = v match {
  case x if classTag[T] == classTag[T1] => "T1"
  case y if classTag[T] == classTag[T2] => "T2"
}
test2(VIn[T1]())  //T1
test2(VIn[T2]())  //T2

List在处理许多示例中使用类型时,我意识到,如果将type参数更改为协变量,则可以在两种测试中使用。

abstract class Co[+T]
case class VCo[T]() extends Co[T]

def test1[T:ClassTag](v:Co[T]) = v match {
  case x : VCo[T1@unchecked] if classTag[T] == classTag[T1] => "T1"
  case y : VCo[T2@unchecked] if classTag[T] == classTag[T2] => "T2"
}
test1(VCo[T1]())  // T1
test1(VCo[T2]())  // T2

def test2[T:ClassTag](v:Co[T]) = v match {
  case x if classTag[T] == classTag[T1] => "T1"
  case y if classTag[T] == classTag[T2] => "T2"
}
test2(VCo[T1]())  // T1
test2(VCo[T2]())  // T2

为什么invarinat类型的第一个测试失败?没有编译器警告或运行时错误,它只是选择第一种情况,但是防护显然是错误的,如中所示test2

贾廷

我绝对认为这是一个编译器错误。

def test1[T:ClassTag](v:In[T]) = {  
  val t1 = classTag[T] == classTag[T1]
  val t2 = classTag[T] == classTag[T2]

  println(v match {
    case x : VIn[T1@unchecked] if t1 => "T1"
    case y : VIn[T2@unchecked] if t2 => "T2"
  })

  v match {
  case x:In[T1] if classTag[T] == classTag[T1] => "T1"
  case y: In[T2] if classTag[T] == classTag[T2] => "T2"
}}

打印时-Xprint:typer显示(evidence):

def test1[T](v: In[T])(implicit evidence$1: scala.reflect.ClassTag[T]): String = {
....

val t1: Boolean = scala.reflect.`package`.classTag[T](evidence$1).==
         (scala.reflect.`package`.classTag[T1]((ClassTag.apply[T1](classOf[T1]): scala.reflect.ClassTag[T1]))) 


val t2: Boolean = scala.reflect.`package`.classTag[T](evidence$1).==        
        (scala.reflect.`package`.classTag[T2]((ClassTag.apply[T2](classOf[T2]): scala.reflect.ClassTag[T2]))) //classTag[T] == classTag[T2]

if模式匹配语句为:

scala.reflect.`package`.classTag[T](evidence$1).==(scala.reflect.`package`.classTag[T1](evidence$1))

scala.reflect.`package`.classTag[T](evidence$1).==(scala.reflect.`package`.classTag[T2](evidence$1))

编译器传递evidence$1到的隐含参数classTag[1]()classTag[2]()因此,它实际上是在将自己与自己进行比较。作为一个变通方案,按照您的建议test2或预先计算的if似乎可行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将开关与数字大小写和字符大小写一起使用

来自分类Dev

如何将SQL连接与大小写一起使用

来自分类Dev

将Scala区分大小写与列表一起使用

来自分类Dev

在Spring Security中与hasPermission一起使用时,权限参数是否区分大小写?

来自分类Dev

如果与sumigniter Select一起使用,如何使用?

来自分类Dev

bash脚本:如果与(条件)或[condition]一起使用

来自分类Dev

如果文件名匹配模式,则执行某些操作(for循环,大小写语句)

来自分类Dev

选择大小写错误的输出和不匹配的错误

来自分类Dev

使用Scala模式匹配而不是Java切换大小写的优点是什么?

来自分类Dev

使用Scala模式匹配而不是Java切换大小写的优点是什么?

来自分类Dev

如何在 Spark2 Scala 中使用大小写匹配模式

来自分类Dev

字符串不区分大小写的模式匹配

来自分类Dev

用sed进行大小写匹配模式替换

来自分类Dev

如何将不区分大小写的模式与ls匹配?

来自分类Dev

切换选择错误的int大小写

来自分类Dev

如果与同步功能一起使用,是否会延迟UI?

来自分类Dev

如果与ClientHttpRequestInterceptor一起使用,Spring Resttemplate postforobject返回null作为对象响应

来自分类Dev

如果与Rails / ActiveRecord一起使用,则Thin是否可以并发?

来自分类Dev

如果与外键约束一起使用,“非空”约束是否多余?

来自分类Dev

如果与&&一起使用,语句如何才能正常工作?

来自分类Dev

如果与fgets()一起使用,chdir()不会更改目录

来自分类Dev

如果与每个任务的ant-contrib一起使用,则多次调用Ant输入

来自分类Dev

如果与 matplotlib.pyplot 一起使用,Tkinter 窗口不会关闭

来自分类Dev

与选择大小写串联

来自分类Dev

选择大小写不是

来自分类Dev

Excel:如果与和/或一起嵌套

来自分类Dev

将zsh的制表符完成与大小写不敏感结合在一起

来自分类Dev

将zsh的制表符完成与大小写不敏感结合在一起

来自分类Dev

使用awk提取特定模式(如果与前一行匹配)

Related 相关文章

  1. 1

    将开关与数字大小写和字符大小写一起使用

  2. 2

    如何将SQL连接与大小写一起使用

  3. 3

    将Scala区分大小写与列表一起使用

  4. 4

    在Spring Security中与hasPermission一起使用时,权限参数是否区分大小写?

  5. 5

    如果与sumigniter Select一起使用,如何使用?

  6. 6

    bash脚本:如果与(条件)或[condition]一起使用

  7. 7

    如果文件名匹配模式,则执行某些操作(for循环,大小写语句)

  8. 8

    选择大小写错误的输出和不匹配的错误

  9. 9

    使用Scala模式匹配而不是Java切换大小写的优点是什么?

  10. 10

    使用Scala模式匹配而不是Java切换大小写的优点是什么?

  11. 11

    如何在 Spark2 Scala 中使用大小写匹配模式

  12. 12

    字符串不区分大小写的模式匹配

  13. 13

    用sed进行大小写匹配模式替换

  14. 14

    如何将不区分大小写的模式与ls匹配?

  15. 15

    切换选择错误的int大小写

  16. 16

    如果与同步功能一起使用,是否会延迟UI?

  17. 17

    如果与ClientHttpRequestInterceptor一起使用,Spring Resttemplate postforobject返回null作为对象响应

  18. 18

    如果与Rails / ActiveRecord一起使用,则Thin是否可以并发?

  19. 19

    如果与外键约束一起使用,“非空”约束是否多余?

  20. 20

    如果与&&一起使用,语句如何才能正常工作?

  21. 21

    如果与fgets()一起使用,chdir()不会更改目录

  22. 22

    如果与每个任务的ant-contrib一起使用,则多次调用Ant输入

  23. 23

    如果与 matplotlib.pyplot 一起使用,Tkinter 窗口不会关闭

  24. 24

    与选择大小写串联

  25. 25

    选择大小写不是

  26. 26

    Excel:如果与和/或一起嵌套

  27. 27

    将zsh的制表符完成与大小写不敏感结合在一起

  28. 28

    将zsh的制表符完成与大小写不敏感结合在一起

  29. 29

    使用awk提取特定模式(如果与前一行匹配)

热门标签

归档