Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 奇怪的“匹配可能不详尽”警告_Scala_Pattern Matching_Inner Classes - Fatal编程技术网

Scala 奇怪的“匹配可能不详尽”警告

Scala 奇怪的“匹配可能不详尽”警告,scala,pattern-matching,inner-classes,Scala,Pattern Matching,Inner Classes,在Scala 2.10.2中 密封抽象A类 海豹{ 密封抽象类B扩展了 最后的C类扩展到B类 最后的D类扩展了B类 最后一类E扩展了A } 对象Main扩展了Foo{ def bar=新C:匹配{ 案例uuC=>C 案例uud=>D 案例u:E=>E } } 编译说 [warn] A.scala:12: match may not be exhaustive. [warn] It would fail on the following inputs: C(), D(), E() [warn]

在Scala 2.10.2中

密封抽象A类 海豹{ 密封抽象类B扩展了 最后的C类扩展到B类 最后的D类扩展了B类 最后一类E扩展了A } 对象Main扩展了Foo{ def bar=新C:匹配{ 案例uuC=>C 案例uud=>D 案例u:E=>E } } 编译说

[warn] A.scala:12: match may not be exhaustive. [warn] It would fail on the following inputs: C(), D(), E() [warn] def bar = (new C(): A) match{ 但主键成功并返回c

我做错什么了吗?还是这是scalac bug


不同foo的路径依赖Cs是不同的

这可能就是它抱怨的原因。警告中存在已知的错误。比如

这更好地代表了您的能力,并使警告静音:

  def bar(a: A) = a match {
    case _: Foo#C => "c"     // instanceof Foo$C etc
    case _: Foo#D => "d"
    case _: Foo#E => "e"
  }
更新:还有更多要说的,也就是说,在查看一个不相关的堆栈溢出时。一个真实的,而不是问答网站

简言之,它试图优化嵌套类到其封闭实例的外部指针,如果发生这种情况,则不能再将外部实例包含在匹配中。通常,它会测试instanceof和它的外层是否正确

将条移动到trait中并删除final将禁用优化并修复匹配

  public static java.lang.String bar(badseal.Foo, badseal.A);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=2
         0: aload_1       
         1: astore_2      
         2: aload_2       
         3: instanceof    #9                  // class badseal/Foo$D
         6: ifeq          26
         9: aload_2       
        10: checkcast     #9                  // class badseal/Foo$D
        13: invokevirtual #13                 // Method badseal/Foo$D.badseal$Foo$D$$$outer:()Lbadseal/Foo;
        16: aload_0       
        17: if_acmpne     26
        20: ldc           #15                 // String d
如果内部类是final,scalac至少会抱怨:

badseal.scala:17: warning: The outer reference in this type test cannot be checked at run time.
    case _: C => "c" 
          ^
但是,如果匹配在对象中,则此消息的启发式似乎会中断,因此您不再看到它

sealed abstract class A

trait Foo {
  sealed abstract class B extends A
  class C extends B
  class D extends B
  class E extends A
  def bar(a: A) = a match {
    case _: C => "c"
    case _: D => "d"
    case _: E => "e"
  }
}

object X extends Foo
然后

正确警告和正确抛出

apm@mara:~/tmp$ skalac -unchecked badseal.scala ; skala badseal.Test
badseal.scala:11: warning: match may not be exhaustive.
It would fail on the following inputs: C(), D(), E()
  def bar(a: A) = a match {
                  ^
one warning found
scala.MatchError: badseal.Foo$C@756bc09d (of class badseal.Foo$C)

不同foo的路径依赖Cs是不同的

这可能就是它抱怨的原因。警告中存在已知的错误。比如

这更好地代表了您的能力,并使警告静音:

  def bar(a: A) = a match {
    case _: Foo#C => "c"     // instanceof Foo$C etc
    case _: Foo#D => "d"
    case _: Foo#E => "e"
  }
更新:还有更多要说的,也就是说,在查看一个不相关的堆栈溢出时。一个真实的,而不是问答网站

简言之,它试图优化嵌套类到其封闭实例的外部指针,如果发生这种情况,则不能再将外部实例包含在匹配中。通常,它会测试instanceof和它的外层是否正确

将条移动到trait中并删除final将禁用优化并修复匹配

  public static java.lang.String bar(badseal.Foo, badseal.A);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=2
         0: aload_1       
         1: astore_2      
         2: aload_2       
         3: instanceof    #9                  // class badseal/Foo$D
         6: ifeq          26
         9: aload_2       
        10: checkcast     #9                  // class badseal/Foo$D
        13: invokevirtual #13                 // Method badseal/Foo$D.badseal$Foo$D$$$outer:()Lbadseal/Foo;
        16: aload_0       
        17: if_acmpne     26
        20: ldc           #15                 // String d
如果内部类是final,scalac至少会抱怨:

badseal.scala:17: warning: The outer reference in this type test cannot be checked at run time.
    case _: C => "c" 
          ^
但是,如果匹配在对象中,则此消息的启发式似乎会中断,因此您不再看到它

sealed abstract class A

trait Foo {
  sealed abstract class B extends A
  class C extends B
  class D extends B
  class E extends A
  def bar(a: A) = a match {
    case _: C => "c"
    case _: D => "d"
    case _: E => "e"
  }
}

object X extends Foo
然后

正确警告和正确抛出

apm@mara:~/tmp$ skalac -unchecked badseal.scala ; skala badseal.Test
badseal.scala:11: warning: match may not be exhaustive.
It would fail on the following inputs: C(), D(), E()
  def bar(a: A) = a match {
                  ^
one warning found
scala.MatchError: badseal.Foo$C@756bc09d (of class badseal.Foo$C)