我知道您可以通过以下方式对列表进行匹配
val list = List(1,2,3)
list match {
case head::tail => head
case _ => //whatever
}
所以我开始怀疑这是如何工作的。如果我理解正确,
::
只是一个运算符,所以阻止我做类似的事情4 match {
case x + 2 => x //I would expect x=2 here
}
如果有一种方法可以创建这种功能,怎么做?如果没有,那为什么呢?
最佳答案
模式匹配采用输入,并使用unapply
函数将其分解。因此,在您的情况下,unapply(4)
将必须返回两个总和为4的数字。但是,有许多总和为4的对,因此该函数将不知道该怎么做。
您需要的是2
函数可以以某种方式访问unapply
。存储2
的特殊情况类适用于此情况:
case class Sum(addto: Int) {
def unapply(i: Int) = Some(i - addto)
}
val Sum2 = Sum(2)
val Sum2(x) = 5 // x = 3
(能够做到像
val Sum(2)(y) = 5
这样的紧凑性很好,但是Scala不允许参数化提取器;请参阅here。)[编辑:这有点愚蠢,但是您实际上也可以执行以下操作:
val `2 +` = Sum(2)
val `2 +`(y) = 5 // y = 3
]
编辑:
head::tail
起作用的原因是,有一种方法可以将头从列表的尾部分开。::
和+
并没有天生的特殊之处:如果您已预先确定要如何破数字,则可以使用+
。例如,如果您希望+
表示“分成两半”,则可以执行以下操作:object + {
def unapply(i: Int) = Some(i-i/2, i/2)
}
并像这样使用它:
scala> val a + b = 4
a: Int = 2
b: Int = 2
scala> val c + d = 5
c: Int = 3
d: Int = 2
编辑:最后,this解释说,在模式匹配时,
A op B
与op(A,B)
含义相同,这使语法看起来不错。
关于scala - 与自定义组合/运算符匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6738577/