Scala 有没有一种方法可以在不使用ISINSTACEOF的情况下匹配除特定类型(或一组类型)以外的所有内容?

Scala 有没有一种方法可以在不使用ISINSTACEOF的情况下匹配除特定类型(或一组类型)以外的所有内容?,scala,Scala,我知道您可以像这样匹配一组类型,而无需使用isInstanceOf: x match { case fooBar @ (_: Foo | _: Bar) => ??? } 但是,除了一组类型之外,还有什么方法可以匹配其他类型吗?例如,匹配任何不是Foo或Bar的x,而无需使用isInstanceOf?好的,您可以这样做 x match { case fooBar @(_: Foo | _: Bar) => // do nothing default => // d

我知道您可以像这样匹配一组类型,而无需使用
isInstanceOf

x match {
  case fooBar @ (_: Foo | _: Bar) => ???
}
但是,除了一组类型之外,还有什么方法可以匹配其他类型吗?例如,匹配任何不是
Foo
Bar
x
,而无需使用
isInstanceOf

好的,您可以这样做

x match {
  case fooBar @(_: Foo | _: Bar) => // do nothing
  default => // do something
}
无论如何,使用
isInstanceOf
的唯一区别是语法,因为您仍将执行运行时检查

从功能角度来看,组合
isInstanceOf
/
asiinstanceof
与类型匹配相同

所以(如果你真的必须的话)我会和你一起去

if (!(x.isInstanceOf[Foo] || x.isInstanceOf[Bar])) {
  // do something
}
同样,这两种方法在实际操作上没有什么区别,它们都是处理类型的一种非常粗糙的方法。除非您使用的是无法控制的外部API,否则我建议您更改设计并避免在类型上进行匹配


通常类型类会派上用场,但如果没有进一步的细节,就很难确定。

以上由@GabrielePetronella提供的解决方案在大多数情况下都很有效,但我添加了另一个变体,可以帮助处理一些边缘情况

边缘案例示例: akka演员的合成
接收功能。
考虑以下事项:

override def receive: Receive = handleFoo orElse handleBar

def handleFoo: Receive = {
  case FooObject => …
  case FooClass(value) => …
  case notFoo => 
    logger.debug(s"wasn't expecting $notFoo of type ${notFoo.getClass.getSimpleName}")
}

def handleBar: Receive = {
  case _: VeryImportantBarMsg => …
  case _: LessImportantBarMsg => …
}
最后一个
handleFoo
案例将捕获所有内容,使
orElse把手
过时,显然我们不再处理
VeryImportantBarMsg
LessImportantBarMsg

解决方案: 使用专用的提取器对象,例如:

object NotBar {
  def unapply[T](t: T): Option[T] = t match {
    case _: VeryImportantBarMsg | _: LessImportantBarMsg => None
    case _ => Some(t)
  }
}
然后像这样使用它:

def handleFoo: Receive = {
  case FooObject => …
  case FooClass(value) => …
  case NotBar(notFoo) => 
    logger.debug(s"wasn't expecting $notFoo of type ${notFoo.getClass.getSimpleName}")
}
此解决方案适用于您不希望匹配成功的情况,如分部函数、akka接收,或者您发现自己多次编写相同的排除类型列表
\uuu:T1 |…\u124;:T10
,等等

附言。
如果您发现自己需要这个解决方案,很可能有些东西没有得到最佳建模。在大多数情况下,这是可以避免的。

我正在使用一个外部API,因此我将听取您的建议,首先匹配我不想要的类型。尽管事情很简单,我却没有想到这一点。谢谢