2013-04-23 47 views
6

scala编译器应该为我在下面评论过的if语句生成警告,但它不会。为什么?为什么scala编译器在模式匹配中总是产生false的if语句不会生成警告?

sealed trait T 
object A extends T 

val s:Seq[T] = Seq(A) 

val result = s.map { 
    //This if should produce a compiler warning 
    case a if(a == "A") => 
     "First" 
    case a => 
     //This if should produce a compiler warning 
     if (a == "A") { 
     "Second" 
     } 
     else 
     { 
     "Third" 
     } 
} 

其结果将是“第三条:”如你所期望,但是编译器应该产生在case a if(a == "A")并在if (a == "A")警告,但可惜没有警告。

如果我写了下面的代码,它的行为像我期望:

if(A == "A"){ 
    println("can't happen") 
} 

// warning: comparing values of types A.type and String using `==' will always yield false 

这究竟是为什么?

编辑:我正在使用Scala 2.10.1。

+0

我相信,当你使用模式匹配,你需要指定每个个案的类型,否则你会匹配任何内容。尝试将其改为“case a:A if(a ==”A“)=> ...”。 – Felix 2013-04-23 18:46:37

+0

我试过用case a:T if(a ==“A”)=>'仍然没有警告。 – coltfred 2013-04-23 18:48:56

回答

1

因为它可能发生。如果我只保留一些内部状态并在第一次和第二次调用时返回==“A”的不同结果,那么我可以得到“Second”。

您已经提供了A的定义来保证它不会发生,但是这需要检查整个程序,而编译器警告只是本地的。

+1

我不确定我了解你的答案。如果我在代码中的任何位置写入表达式“if(A ==”a“){}',我会得到编译器的警告,但是你说模式匹配会使声明的局部性变得重要吗?请澄清。 – coltfred 2013-04-23 20:04:46

0

也许你会继承类重载==方法用字符串参数...

+0

的确如此,但编译器知道这些信息。我和Josh Suereth一起讨论了这个问题,他在类型安全方面工作,他的回答如下:“编译器不生成警告不是一个错误,但我们希望警告更强健。”所以虽然它不是一个“bug”,但它没有实现。 – coltfred 2013-05-01 03:45:14

+0

所以,我希望我们能在将来的Scala编译器发布中看到这个警告:) – aeracode 2013-05-01 16:31:48

相关问题