Scala совпадение / регистр при сопоставлении интерфейсов Java - PullRequest
3 голосов
/ 02 мая 2011

Я использую оператор Scala match/case, чтобы соответствовать интерфейсу данного Java-класса. Я хочу иметь возможность проверить, реализует ли класс комбинацию интерфейсов. Единственный способ заставить это работать - использовать вложенные операторы match/case, которые кажутся уродливыми.

Допустим, у меня есть объект PersonImpl, который реализует Person, Manager и Investor. Я хочу видеть, реализует ли PersonImpl и Менеджера и Инвестора. Я должен быть в состоянии сделать следующее:

person match {
  case person: (Manager, Investor) =>
    // do something, the person is both a manager and an investor
  case person: Manager =>
    // do something, the person is only a manager
  case person: Investor =>
    // do something, the person is only an investor
  case _ =>
    // person is neither, error out.
}

case person: (Manager, Investor) просто не работает. Чтобы заставить это работать, я должен сделать следующее, которое кажется уродливым.

person match {
  case person: Manager = {
    person match {
      case person: Investor =>
        // do something, the person is both a manager and investor
      case _ =>
        // do something, the person is only a manager
    }
  case person: Investor =>
    // do something, the person is only an investor.
  case _ =>
    // person is neither, error out.
}

Это просто безобразно. Есть предложения?

1 Ответ

8 голосов
/ 02 мая 2011

Попробуйте это:

case person: Manager with Investor => // ...

with используется для других сценариев, где вы можете выразить пересечение типов, например, в границах типа:

def processGenericManagerInvestor[T <: Manager with Investor](person: T): T  = // ...

Кстати - не то, чтобы это рекомендованная практика , но - вы также всегда можете проверить это так: if (person.isInstanceOf[Manager] && person.isInstanceOf[Investor]) ....


Редактировать: это хорошо работает для меня:

trait A
trait B
class C

def printInfo(a: Any) = println(a match {
  case _: A with B => "A with B"
  case _: A => "A"
  case _: B => "B"
  case _ => "unknown"
})

def main(args: Array[String]) {
  printInfo(new C)               // prints unknown
  printInfo(new C with A)        // prints A
  printInfo(new C with B)        // prints B
  printInfo(new C with A with B) // prints A with B
  printInfo(new C with B with A) // prints A with B
}
...