简体   繁体   English

如何模式匹配扩展多个特征的对象?

[英]How to pattern match an object that extends multiple traits?

I have a super class Command , many different subclasses extend from Command and at the same time may also extend one or more of these traits ValuesCommand , KeysCommand , MembersCommand and many others. 我有一个超类Command ,许多不同的子类从Command扩展,同时也可以扩展这些特性中的一个或多个ValuesCommandKeysCommandMembersCommand和许多其他。

Now I want to pattern match all implementations of Command that extend a ValuesCommand and KeysCommand at the same time. 现在我想模式匹配Command所有实现,同时扩展ValuesCommandKeysCommand

Here is some pseudocode of what I want to achieve: 这是我想要实现的一些伪代码

def apply(cmd : Command) = {
  cmd match {
    case c:(ValuesCommand && KeysCommand) => c.doSomething()
  }
}

I could fallback to match the first trait and nest a second match . 我可以回退以匹配第一个特征并嵌套第二match But I don't really need it and looks terrible. 但我真的不需要它,看起来很糟糕。

You can do it like this: 你可以这样做:

def apply(cmd : Command) = {
  cmd match {
    case c: ValuesCommand with KeysCommand => c.doSomething()
  }
}

When you have a class (eg ValKey here) that both extends ValuesCommand and KeysCommand you also have something like 如果你有一个类(例如这里的ValKey ),它们都扩展了ValuesCommandKeysCommand你也有类似的东西

class ValKey extends ValuesCommand with KeysCommand`

Edit (Your comment): 编辑(您的评论):

I can't imagine a scenario where you want something like ValuesCommand or KeysCommand in this case. 在这种情况下,我无法想象你想要一些像ValuesCommand or KeysCommand这样的场景。 You can read the link in @Randall Schulz comment to see how to get an OR. 您可以阅读@Randall Schulz评论中的链接,了解如何获得OR。

Let's imagine you have your OR (v), like described in the link. 让我们假设您有OR(v),如链接中所述。

case c: ValuesCommand v KeysCommand => //soo.. what is c?

Now you still have to pattern-match on c to find out what kind of command it is. 现在你仍然需要在c上进行模式匹配以找出它是什么类型的命令。 (most likely) (最有可能的)

So in the end you can still do it directly like this: 所以最后你仍然可以像这样直接做到:

cmd match {
  case vc: ValuesCommand => vc.doSomething()
  case kc: KeysCommand   => kc.doSomehtingElse()
}

Edit2: EDIT2:

For a scenario where you want to call your accept method on cmd , only if it is a ValuesCommand or KeysCommand , you can do: 对于要在cmd上调用accept方法的场景,仅当它是ValuesCommandKeysCommand ,您可以执行以下操作:

cmd match {
  case _: ValuesCommand | _: KeysCommand => accept(cmd)
}

which, i guess, is more DRY than 我猜,这比干的更干

cmd match {
  case vc: ValuesCommand => accept(cmd)
  case kc: KeysCommand   => accept(cmd)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM