scala - 与自定义组合/运算符匹配

标签 scala pattern-matching

我知道您可以通过以下方式对列表进行匹配

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 Bop(A,B)含义相同,这使语法看起来不错。

关于scala - 与自定义组合/运算符匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6738577/

相关文章:

json - 如何解析包含在 Scala 中始终更改名称的字段的 json?

scala - Spark : udf to get dirname from path

types - 直接在 F# 中匹配类型(不是对象,实际的 System.Type)

python - 使用滚动窗口准确检测数据帧中具有重复值(相同头部和相同尾部)的序列

scala - 尝试将 Spark DF 写入 Hive 表时出现错误 "Invalid call to qualifier on unresolved object"

json - 在Spray POST路由内提取原始JSON作为字符串

web-services - spray-can webservice 优雅关闭

python - 我们可以在 Python 中替换时引用字典从键中获取值吗?

java - 序列号的模式匹配算法

java - 为什么这些正则表达式在 Java 中执行起来很慢?