Scala 如何对扩展了多个特征的对象进行模式匹配?
我有一个超类Scala 如何对扩展了多个特征的对象进行模式匹配?,scala,pattern-matching,traits,Scala,Pattern Matching,Traits,我有一个超类Command,许多不同的子类从Command扩展而来,同时还可以扩展一个或多个特征ValuesCommand,KeysCommand,MembersCommand和许多其他特征 现在,我想对同时扩展ValuesCommand和KeysCommand的Command的所有实现进行模式匹配 以下是我想要实现的一些伪代码: def apply(cmd : Command) = { cmd match { case c:(ValuesCommand && Key
Command
,许多不同的子类从Command扩展而来,同时还可以扩展一个或多个特征ValuesCommand
,KeysCommand
,MembersCommand
和许多其他特征
现在,我想对同时扩展ValuesCommand
和KeysCommand
的Command
的所有实现进行模式匹配
以下是我想要实现的一些伪代码:
def apply(cmd : Command) = {
cmd match {
case c:(ValuesCommand && KeysCommand) => c.doSomething()
}
}
我可以退一步来匹配第一个特征,然后嵌套第二个
匹配。但是我真的不需要它,而且看起来很糟糕。你可以这样做:
def apply(cmd : Command) = {
cmd match {
case c: ValuesCommand with KeysCommand => c.doSomething()
}
}
cmd match {
case vc: ValuesCommand => vc.doSomething()
case kc: KeysCommand => kc.doSomehtingElse()
}
当您拥有一个既扩展了ValuesCommand
又扩展了KeysCommand
的类(例如这里的ValKey
)时,您还有
class ValKey extends ValuesCommand with KeysCommand`
编辑(您的评论):
我无法想象在这种情况下,您需要像ValuesCommand或KeysCommand这样的命令。您可以阅读@Randall Schulz评论中的链接,了解如何获得OR
让我们想象一下,你有你的OR(v),就像链接中描述的那样
case c: ValuesCommand v KeysCommand => //soo.. what is c?
现在您仍然需要在c
上进行模式匹配,以了解它是哪种命令。(最有可能)
所以最后你还是可以直接这样做:
def apply(cmd : Command) = {
cmd match {
case c: ValuesCommand with KeysCommand => c.doSomething()
}
}
cmd match {
case vc: ValuesCommand => vc.doSomething()
case kc: KeysCommand => kc.doSomehtingElse()
}
编辑2:
对于希望在cmd
上调用accept方法的场景,仅当它是ValuesCommand
或KeysCommand
时,您可以执行以下操作:
cmd match {
case _: ValuesCommand | _: KeysCommand => accept(cmd)
}
我想这比我想象的要干
cmd match {
case vc: ValuesCommand => accept(cmd)
case kc: KeysCommand => accept(cmd)
}
也许更好的方法是在traitsValuesCommand
和KeysCommand
中重写(或抽象重写)doSomething
方法?在这种情况下,您不需要执行模式匹配,我很想这样做,但我正在处理的代码不是我的:它来自一个我不想使用fork(Finagle Redis)的库,从逻辑上讲,与
是连接的。两个类型标识都必须存在才能获取。至少在一开始,有点让人吃惊的是,在Scala中可以得到非固定的静态析取(非此即彼,也称为并集)类型的合成!查看所有的乐趣。带有
的工作完美,对我来说很有意义。但是|
呢?例:案例c:(ValuesCommand | | KeysCommand)=>c.doSomething()我不明白为什么OR是一个奇怪的案例:在这种模式匹配中,我想调用accept(cmd:Command)函数KeysCommand或ValuesCommand对象。我不需要确切地知道or条件的哪一部分已经匹配,因为从现在起我将把对象作为命令处理。当然,您使用“v”的伪代码应该省略“c:”,因为我认为您会直接将对象称为cmd。很好,这正是我想要的。非常感谢,先生。