【问题标题】:Scala _ Placeholders (How does this code function?)Scala _ 占位符(这段代码如何运作?)
【发布时间】:2011-10-16 08:41:24
【问题描述】:

我正在学习 Scala(主要来自 Java 背景)。我正在尝试围绕以下代码进行思考:

object Main {
  def main(args : Array[String]) {
    for (file <- filesEnding(".txt"))
      println(file.getName)
  }

  private val filesHere = (new java.io.File(".")).listFiles

  def filesMatching(matcher: String => Boolean) =
    for (file <- filesHere; if matcher(file.getName))
        yield file

  def filesEnding(query: String) = filesMatching(_.endsWith(query))
  /* Other matcher functions */
}

特别是我很困惑 Scala 在每个匹配器函数中获取_ 的值。我可以看到filesEnding 是用.txt 的参数调用的。该参数分配给queryfilesEnding 然后使用与String =&gt; Boolean 函数一致的参数调用filesMatching。最后我可以看到 file.getName 最终取代了 _ 占位符。

我不明白 Scala 怎么知道用 file.getName 代替 _。我无法在脑海中追踪这段代码,而 Eclipse 调试器在这种情况下并没有多大帮助。有人可以告诉我这段代码中发生了什么吗?

【问题讨论】:

  • 关于这方面的一点提醒/建议:尽量避免使用下划线。它会为您省去一些麻烦!
  • @Andreas 我不明白为什么我应该尽量避免使用下划线。对于 filtermap 等方法的简单参数,它非常有意义,不会造成麻烦并减少混乱。
  • 是的,对于非常简单的语句,它可以正常工作,当然它是为工作而设计的;)但问题是(恕我直言)它所涉及的! scala 中的 13 种不同含义。

标签: scala functional-programming placeholder


【解决方案1】:

_ 只是创建匿名函数的简写:

_.endsWith(query)

和匿名函数一样

fileName => fileName.endsWith(query)

这个函数然后作为matcher 的参数输入到filesMatching。在该函数中,您可以看到调用

matcher(file.getName)

这会以file.getName 作为_ 参数调用匿名函数(在显式示例中我称之为fileName)。

【讨论】:

  • 看起来它只有在匿名函数接受一个参数时才有效。是否可以将它用于多个参数?如果不是,语言规范的哪一部分解释了它?
【解决方案2】:

如果你写_.someMethod(someArguments),这个去糖到x =&gt; x.someMethod(someArguments),所以filesMatching(_.endsWith(query))去糖到filesMatching(x =&gt; x.endsWith(query))

所以filesMatching 被调用时matcher 是函数x =&gt; x.endsWith(query),即一个函数,它接受一个参数x 并在该参数上调用x.endsWith(query)

【讨论】:

  • 哦,我喜欢“脱糖”这个词。我将开始使用它。
  • @KPthunder "饮食"
猜你喜欢
  • 1970-01-01
  • 2014-10-12
  • 2018-07-30
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 2014-02-20
  • 2013-03-13
相关资源
最近更新 更多