【问题标题】:Scala match/case statement when matching Java Interfaces匹配 Java 接口时的 Scala match/case 语句
【发布时间】:2011-05-02 15:55:55
【问题描述】:

我正在使用 Scala match/case 语句来匹配给定 java 类的接口。我希望能够检查一个类是否实现了接口的组合。我似乎可以让它工作的唯一方法是使用嵌套的 match/case 语句,这看起来很丑。

假设我有一个 PersonImpl 对象,它实现了 Person、Manager 和 Investor。我想看看 PersonImpl 是否同时实现了 Manager 和 Investor。我应该能够做到以下几点:

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

这简直丑陋。有什么建议吗?

【问题讨论】:

  • case person: Manager with Investor 应该可以工作。当你对这些你说只是Manager 的对象调用Investor 方法时会发生什么?
  • 如果您能接受答案或告诉我们您想了解的有关此主题的其他信息,那就太好了。

标签: scala pattern-matching


【解决方案1】:

试试这个:

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

with 用于您可能想要表达类型交集的其他场景,例如在类型绑定中:

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

顺便说一句——不是推荐的做法,但是——你也可以像这样测试它:if (person.isInstanceOf[Manager] &amp;&amp; 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
}

【讨论】:

  • 我刚刚测试了案例人:经理和投资者,不幸的是它没有用。它捕获仅实现 Manager 的人员以及同时实现这两者的人员。这是一个错误吗?
  • 有趣。我在我的答案中添加了一个简短的例子,它适用于 Scala 2.8.1。你用的是哪个版本?
  • 你是对的。我刚刚运行了您的示例,它起作用了。就我而言,我没有使用特征,因为“类”是一个 java 并且正在实现一个接口,但我认为这并不重要。
  • 因为我的情况不是纯 scala,它是 scala、java 的混合物,这是我必须做的才能让它工作。 person match { case person if (person.isInstanceOf[Manager] && person.isInstanceOf[Investor]) => // 做某事,人既是经理又是投资者 case person: Manager => // 做某事,这个人只是一个经理 case person: Investor => // 做某事,这个人只是一个投资者 case _ => // 这个人都不是,错误输出。我仍然不喜欢这个,但它比嵌套的 case 语句更好。
  • 即使我在 Java 中定义了 ABC,它也适用于我。对我来说听起来像是一个错误。您是自己编译 Java 类吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2018-02-02
  • 2017-08-06
  • 2011-10-17
  • 2013-10-11
  • 1970-01-01
相关资源
最近更新 更多