带有模式匹配的 Scala 部分应用函数

标签 scala

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

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 被分配了“匹配的 ”,因为它调用了匹配 'f' 作为值。

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

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

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

最佳答案

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

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
}

关于带有模式匹配的 Scala 部分应用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11112782/

相关文章:

java - IS NULL 条件下的 JDBC 错误

scala - 在 Scala 中元素-值对列表中的惯用值搜索

Scala AKKA 访问变量或返回值

scala - 从 scalastyle sbt 插件中排除文件夹

Scala 2.8.0.RC2 编译器关于模式匹配语句的问题?

scala - 用于将列表映射到列表元素顺序的简单 Scala 代码。 (用于生成行号)

scala - Haskell 中的哪些功能无法用 Scala 模拟?

scala - 使用相互递归函数时,是否有一种简单的方法来处理流?

scala - 如何使用VTD-XML库在Scala中解析XML文件?

python相当于scala分区