【问题标题】:Scala underscore minimal functionScala 强调最小功能
【发布时间】:2010-12-12 14:06:47
【问题描述】:

让我们为这个问题创建一个值:

val a = 1 :: Nil

现在,我可以证明匿名函数可以写成这样的简写形式:

a.map(_*2)

这个函数可以写一个简写吗?:

a.map((x) => x)

我的解决方案不起作用:

a.map(_)

【问题讨论】:

  • 没有多大意义,是吗?这只是一个 NOP。
  • 这只是一个例子。它可以在上下文中有意义
  • 这是一个很好的例子,说明 Scala 中过度使用(恕我直言)“_”糖确实使人们难以掌握该语言。

标签: scala anonymous-function


【解决方案1】:

郑重声明,a.map(_) 不起作用,因为它代表x => a.map(x),而不是a.map(x => x)。发生这种情况是因为单个_ 代替参数代表部分应用函数。对于2*_,它代表一个匿名函数。这两种用途非常接近,很容易被它们混淆。

【讨论】:

  • 其实这两种用法是一样的,“占位符语法”。该规范没有使用“部分应用”这个短语;更改日志仅将其用于m _ 语法; Scala 中的编程首先将其用于m _,然后用于m(_)。但是f(_) 在语法上类似于if (_)。 “部分应用程序”在推断参数类型时获得帮助。
  • 嗯,那我想知道为什么我们不能有类似val pFunc = a.map(_) 的东西?
  • @SpiXel 可以,但是需要指定pFunc的类型。并不是说map 需要一个函数,所以x => a.map(x) 中的x 将是从Int 到某种类型的函数。无法推断这是什么类型,因此,您需要为 pFunc 指定类型,此时 Scala 会很乐意接受该行。
【解决方案2】:

您的第一个速记形式也可以无点书写

a map (2*)

感谢乘法是可交换的。

对于(x) => x,您需要identity 函数。这是在 Predef 中定义的并且是通用的,因此您可以确定它是类型安全的。

【讨论】:

  • 我认为你的意思是可交换的。
  • 很遗憾x=>x是四个字符,而identity是八个字符。这就是为什么我从不使用identity
  • @debilski 你知道这东西不容易!当一个 18 个月大的孩子为使用键盘而战时,这不是!
  • @Rex identity 可能是 8 个字母,但它仍然是一个标识符,因此更容易解析(对于人类和编译器)
  • @Rex AST 会有所不同...而且我仍然看到我的眼睛被那个箭头所吸引:)
【解决方案3】:

对于这个用例,您应该使用identity 函数。

a.map(identity)

identityscala.Predef 中定义为:

implicit def identity[A](x: A): A = x 

【讨论】:

    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多