开发者

Scala match/case statement when matching Java Interfaces

开发者 https://www.devze.com 2023-03-01 22:09 出处:网络
I\'m using the Scala match/case statement to match an interface of a given java class. I want to be able to check if a class implements a combination of interfaces. The only way I can seem to get this

I'm using the Scala match/case statement to match an interface of a given java class. I want to be able to check if a class implements a combination of interfaces. The only way I can seem to get this to work is to use nested match/case statements which seems ugly.

Lets say I have a PersonImpl object which implements Person, Manager and Investor. I want to see if PersonImpl implements both Manager and Investor. I should be able to do the following:

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 neithe开发者_运维技巧r, error out.
}

The case person: (Manager, Investor) just doesn't work. In order to get it to work I have to do the following which seem ugly.

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.
}

This is just plain ugly. Any suggestions?


Try this:

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

with is used for other scenarios where you might want to express type intersection, e.g. in a type bound:

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

By the way — not that this is recommended practice, but — you can always test it like this as well: if (person.isInstanceOf[Manager] && person.isInstanceOf[Investor]) ....


Edit: this works well for me:

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
}
0

精彩评论

暂无评论...
验证码 换一张
取 消