4

我出于好奇发布这个问题,看看是否有人知道在以下情况下模式匹配是如何工作的。假设我有一个函数值定义如下:

val f = (s: String) => s.toInt

它的类型当然是 String => Int。现在我想创建一个基于模式匹配传递给该函数的任何内容的输出的新函数。我可以定义如下:

val f2 = f(_: String) match {
  case i: Int => i + 2
}

现在我的新函数也来自 String => Int,但是在这个过程中它加了 2。可以这样调用:

scala> f2("3")
res0: Int = 5

如果我在不做部分应用的情况下做同样的事情,那么我会根据函数本身得到一个匹配:

val f3 = f match {
  case x => "matched: " + x
}

现在,值 f3 被分配“匹配的 <function1>”,因为它以 'f' 作为值调用 match。

所以我的问题是,Scala 如何区分这两者?它们都是函数值,并且都是 String => Int 类型。事实上,如果我在运行 match 之前将部分应用的函数值分配给临时变量 tmp,那么它的行为与 f3 相同:

val tmp = f(_: String)
val f4 = tmp match {
  case x => "matched: " + x
}

现在 f4 被分配“匹配的 <function1>”而不是函数 String => Int。

我可以看到想要做的价值,我只是好奇它是如何完成的。这只是 Scala 添加的一些魔法吗,它以某种方式发现你在匹配的上下文中部分应用了一个函数,所以它会产生一些不同的东西......

4

1 回答 1

9

这就是下划线的工作方式。

f(_: String) match {
  case i: Int => i + 2
}

是的简写

(x: String) => (f(x) match {
  case i: Int => i + 2
})

(添加括号以使事情更清楚)但您的其他示例等效于

(x: String => f(x)) match {
  case y => "matched: " + y
}
于 2012-06-20T06:02:08.870 回答