Zastanawiam się, jak mogę użyć dopasowania wzorców wielu typów. Mam:
abstract class MyAbstract
case class MyFirst extends MyAbstract
case class MySecond extends MyAbstract
case class MyThird extends MyAbstract // shouldn't be matched and shouldn't call doSomething()
val x: MyAbstract = MyFirst
x match {
case a: MyFirst => doSomething()
case b: MySecond => doSomething()
case _ => doSomethingElse()
}
Więc chciałbym napisać coś takiego:
x match {
case a @ (MyFirst | MySecond) => doSomething()
case _ => doSomethingElse()
}
Widziałem podobną konstrukcję w jakimś tutorialu, ale daje mi błąd:
pattern type is incompatible with expected type;
[error] found : object MyFirst
[error] required: MyAbstract
Czy jest więc sposób na zdefiniowanie kilku różnych typów w klauzuli on case? Myślę, że dzięki temu kod byłby ładniejszy. Jakbym miał ich 5, napiszę ten sam kod 5 razy (wywołując doSomething ()).
Z góry dziękuję!
scala
types
pattern-matching
psisoyev
źródło
źródło
doSomething
przypadków, dlaczego nie dopasowaćcase a : MyAbstract
wtedy ...?Odpowiedzi:
Brakuje nawiasów dla klas przypadków. Klasy przypadków bez list parametrów są przestarzałe.
Spróbuj tego:
abstract class MyAbstract case class MyFirst() extends MyAbstract case class MySecond() extends MyAbstract val x: MyAbstract = MyFirst() x match { case aOrB @ (MyFirst() | MySecond()) => doSomething(aOrB) case _ => doSomethingElse() }
Jeśli masz zbyt wiele parametrów dla klas przypadków i nie lubisz pisać długich
Foo(_,_,..)
wzorców, to może:x match { case aOrB @ (_:MyFirst | _:MySecond) => doSomething(aOrB) case _ => doSomethingElse() }
Lub tylko:
x match { case _:MyFirst | _:MySecond => doSomething(x) // just use x instead of aOrB case _ => doSomethingElse(x) }
Ale może po prostu chciałeś mieć pojedyncze obiekty?
abstract class MyAbstract case object MyFirst extends MyAbstract case object MySecond extends MyAbstract val x: MyAbstract = MyFirst x match { case aOrB @ (MyFirst | MySecond) => doSomething() case _ => doSomethingElse() }
źródło
obj @ (_: MyFirst | _: MySecond)
?obj
w przypadkach, w których używam go wdoSomething
rozmowie. W moim przypadku połączeniedoSomething
nie było używaneobj
, więc go nie potrzebuję. Ale tak czy inaczej, dziękuję za komentarz!