Предупреждение матча может быть не исчерпывающим - PullRequest
0 голосов
/ 19 декабря 2018

Я пробовал код ниже:

  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")
  }

Но, когда я пытаюсь запустить его в IntelliJ, на вкладке Messages выдается предупреждение ниже:

Warning:(11, 16) match may not be exhaustive.
It would fail on the following inputs: false, true
  set1.contains(4) match {

Принимая во внимание, что если я использую true и false вместо TRUE_BOOLEAN и FALSE_BOOLEAN, я не получу никаких предупреждений.

set1.contains(4) match {
    case true => println("Element found")
    case false => println("Element not found")
  }

Может кто-нибудь объяснить причину этого предупрежденияи почему это уходит с true и false.

1 Ответ

0 голосов
/ 19 декабря 2018

Выдает предупреждение, потому что не может гарантировать, что совпадение является исчерпывающим.

Действительно, при внедрении в правильный контекст ваш код выдает ошибку совпадения во время выполнения:

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)

таким образом, предупреждение правильно , а не просто чрезмерно консервативная оценка.Поскольку каждый скрипт Scala неявно внедряется в некоторую «классовую» оболочку, он также работает в скриптах Scala точно так же, даже если вы не заключаете его в класс Foo.

Если вы установите обе переменные на final, то постоянное распространение будет работать правильно, и предупреждение не выдается:

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")
  }
}

компилируется просто отлично, без предупреждений.

...