scala - 管理下划线以定义匿名函数的规则是什么?

标签 scala lambda anonymous-function partial-application scala-placeholder-syntax

我正在使用 _作为创建匿名函数的占位符,问题是我无法预测 Scala 将如何转换我的代码。更准确地说,它错误地确定了我想要的匿名函数有多“大”。

 List(1,2,3) foreach println(_:Int)   //error !
 List(1,2,3) foreach (println(_:Int)) //work
 List(1,2,3) foreach(println(_:Int))  //work

使用 -Xprint:typer我可以看到 Scala 将第一个转换为“一个大的匿名函数”:
x$1 => List(1,2,3) foreach(println(x$1:Int))

工作的第 2 次第 3 次正确转变为我想要的。
... foreach (x$1 => println(x$1:Int)) 

为什么这个?有什么规律?

最佳答案

确定下划线范围的简单规则:

  • 如果下划线是方法的参数,则范围将在该方法之外,否则分别遵循以下规则;
  • 如果下划线位于由 () 或 {} 分隔的表达式内,则将使用包含下划线的最里面的分隔符;
  • 在所有其他条件相同的情况下,将使用可能的最大表达式。

  • 因此,根据规则 #1,而不是 println((x: Int) => x) ,范围将放在(包括)println 之外.

    根据规则 #2,后两个示例将具有由括号分隔的函数,因此 (x => println(x: Int)) .

    根据规则 #3,第一个示例将是整个表达式,因为没有分隔括号。

    关于scala - 管理下划线以定义匿名函数的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28125850/

    相关文章:

    java - 如何在lambda表达式(JAVA)中使用try catch?

    java - 如何将参数发送到流中的引用方法(java 8)?

    scala - 将无形的HList转换为较小的HList

    scala - SBT:子项目中的 plugins.sbt 被忽略?

    scala - Apache-Spark 内部作业调度

    generics - 如何在带有 React 的 Typescript/JSX 中使用带有箭头函数的泛型?

    matlab - 如何使用匿名函数实现不同操作的向量输入/输出?

    swift - 没有花括号和参数标签的匿名函数?

    javascript - 一个脚本中多个自调用函数出错 : a case for a semicolon

    scala - 如何使用spark将来自kafka主题的流数据写入hdfs?