I was trying out below code:
val set1 = Set(1,2,3,4,5,67,8)
val TRUE_BOOLEAN = true
val FALSE_BOOLEAN = false
set1.contains(4) match {
case TRUE_BOOLEAN => println("Element found")
case FALSE_BOOLEAN => println("Element not found")
}
But, when i am trying to run it in IntelliJ
, it is giving below warning in Messages
tab:
Warning:(11, 16) match may not be exhaustive.
It would fail on the following inputs: false, true
set1.contains(4) match {
Whereas, if i use true
and false
instead of TRUE_BOOLEAN
and FALSE_BOOLEAN
, i am not getting any warning.
set1.contains(4) match {
case true => println("Element found")
case false => println("Element not found")
}
Can someone please explain the reason for this warning and why does it goes away with true
and false
.
It produces a warning, because it cannot guarantee that the match is exhaustive.
Indeed, when embedded in the right context, your code throws a match error at runtime:
class Foo {
val set1 = Set(1,2,3,4,5,67,8)
val TRUE_BOOLEAN = true
val FALSE_BOOLEAN = false
set1.contains(4) match {
case TRUE_BOOLEAN => println("Element found")
case FALSE_BOOLEAN => println("Element not found")
}
}
class Bar extends Foo {
override val TRUE_BOOLEAN = false
}
new Bar // scala.MatchError: true (of class java.lang.Boolean)
so the warning is correct, and not merely an over-conservative estimate. Since every Scala script is implicitly embedded into some "class-like" wrapper, it also works in Scala scripts in exactly the same way, even if you don't wrap it in a Foo
-class.
If you set both variables to final
, then constant propagation works properly, and no warning is emitted:
class Foo {
val set1 = Set(1,2,3,4,5,67,8)
final val TRUE_BOOLEAN = true
final val FALSE_BOOLEAN = false
set1.contains(4) match {
case TRUE_BOOLEAN => println("Element found")
case FALSE_BOOLEAN => println("Element not found")
}
}
compiles just fine, no warnings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With