По-добра проверка на типа при съвпадение в Scala

scala> class A
defined class A

scala> class B
defined class B

scala> val a: A = new A
a: A = A@551510e8

scala> a match {
     | case _: B => println("unlikely")
     | case _ => println("no match")
     | }
no match

В горния пример не трябва ли компилаторът да ми каже, че един от случаите никога не може да съвпадне? Малко по-сложен пример наскоро ме хвана, което доведе до нещо, което се чувствах като ненужен бъг, който трябваше да бъде уловен от компилатора.

Редактиране:

Само за по-ясен въпрос. Това невъзможно ли е в Scala по някаква причина, която не виждам? (Мога да разбера дали типовете са използвали генерични и изтриването на типове е причинявало проблеми, но това изглежда доста ясно.) И ако това не е невъзможно, има ли законни причини това да не е в Scala? Ако не, кога ще бъде добавено? ;)


person David    schedule 02.08.2010    source източник


Отговори (3)


Понастоящем проверката за изчерпателност и излишък се извършва само за шаблони на конструктор на клас case. По принцип компилаторът може да направи това и за някои други видове модели. Но в SLS трябва да се уточни точно какви тестове се правят. Това изглежда осъществимо, но нетривиално, предвид взаимодействията между различните класове шаблони. И така, в обобщение, това е една от областите в Scala, които биха спечелили от по-нататъшни приноси.

person Martin Odersky    schedule 02.08.2010
comment
невероятно! Отговарям на този, който ме научи на scala и също я измисли! Thx stackoverflow! - person Kami; 04.08.2010

Компилаторът ви предупреждава (всъщност компилацията е неуспешна), ако използвате класове case:

scala> case class A()
defined class A

scala> case class B()
defined class B

scala> val a = A()
a: A = A()

scala> a match {
     | case A() => println("A")
     | case B() => println("B")
     | case _ => println("_")
     | }
<console>:13: error: constructor cannot be instantiated to expected type;
 found   : B
 required: A
       case B() => println("B")
person michid    schedule 02.08.2010
comment
За съжаление класовете case имат някои ограничения и не винаги са подходящи. Не виждам защо компилаторът не може да разбере това и за нормалните класове. - person David; 02.08.2010

Проверих в Scala 2.13.3, получаваме предупреждение за fruitless type test:

scala> a match {
     | case _:B => println("B")
     | case _ => println("no match")
     | }
       case _:B => println("B")
              ^
On line 2: warning: fruitless type test: a value of type A cannot also be a B
no match
person Saurav Sahu    schedule 13.02.2021