是否可以在一个匹配语句中运行多个提取器?
object CoolStuff {
def unapply(thing: Thing): Option[SomeInfo] = ...
}
object NeatStuff {
def unapply(thing: Thing): Option[OtherInfo] = ...
}
// is there some syntax similar to this?
thing match {
case t @ CoolStuff(someInfo) @ NeatStuff(otherInfo) => process(someInfo, otherInfo)
case _ => // neither Cool nor Neat
}
Run Code Online (Sandbox Code Playgroud)
这里的意图是有两个提取器,我不必做这样的事情:
object CoolNeatStuff {
def unapply(thing: Thing): Option[(SomeInfo, OtherInfo)] = thing match {
case CoolStuff(someInfo) => thing match {
case NeatStuff(otherInfo) => Some(someInfo -> otherInfo)
case _ => None // Cool, but not Neat
case _ => None// neither Cool nor Neat
}
}
Run Code Online (Sandbox Code Playgroud)
可以尝试
object ~ {
def unapply[T](that: T): Option[(T,T)] = Some(that -> that)
}
def too(t: Thing) = t match {
case CoolStuff(a) ~ NeatStuff(b) => ???
}
Run Code Online (Sandbox Code Playgroud)
我提出了一个非常相似的解决方案,但我有点太慢了,所以我没有将其发布为答案。然而,由于 @userunknown 要求解释它是如何工作的,所以我无论如何都会在这里转储类似的代码,并添加一些注释。也许有人发现它是 cchantep 简约解决方案的一个有价值的补充(它看起来……书法?出于某种原因,从某种意义上来说)。
所以,这是我的类似的、美学上不太令人愉悦的建议:
object && {
def unapply[A](a: A) = Some((a, a))
}
// added some definitions to make your question-code work
type Thing = String
type SomeInfo = String
type OtherInfo = String
object CoolStuff {
def unapply(thing: Thing): Option[SomeInfo] = Some(thing.toLowerCase)
}
object NeatStuff {
def unapply(thing: Thing): Option[OtherInfo] = Some(thing.toUpperCase)
}
def process(a: SomeInfo, b: OtherInfo) = s"[$a, $b]"
val res = "helloworld" match {
case CoolStuff(someInfo) && NeatStuff(otherInfo) =>
process(someInfo, otherInfo)
case _ =>
}
println(res)
Run Code Online (Sandbox Code Playgroud)
这打印
[helloworld, HELLOWORLD]
Run Code Online (Sandbox Code Playgroud)
这个想法是标识符(特别&&是~在 cchantep 的代码中)可以用作paths 中的中缀运算符。因此,match-case
case CoolStuff(someInfo) && NeatStuff(otherInfo) =>
Run Code Online (Sandbox Code Playgroud)
将被脱糖成
case &&(CoolStuff(someInfo), NeatStuff(otherInfo)) =>
Run Code Online (Sandbox Code Playgroud)
然后unapply方法方法&&将被调用,它只是复制其输入。
在我的代码中,复制是通过简单的Some((a, a)). 在 cchantep 的代码中,它是用更少的括号完成的:Some(t -> t)。箭头->来自ArrowAssoc,它又作为 中的隐式转换提供Predef。这只是创建对的快速方法,通常在地图中使用:
Map("hello" -> 42, "world" -> 58)
Run Code Online (Sandbox Code Playgroud)
另注:注意&&可以多次使用:
case Foo(a) && Bar(b) && Baz(c) => ...
Run Code Online (Sandbox Code Playgroud)
所以...我不知道这是否是对 cchantep 答案的答案或扩展评论,但也许有人发现它有用。
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |