Scala IDE警告:"匿名函数可转换为方法值"

Use*_*291 6 methods alias scala anonymous-function

假设我想为方法创建一个别名:

def foo = bar(_)
Run Code Online (Sandbox Code Playgroud)

这将警告

匿名函数可转换为方法值

而且我不太确定这是什么意思,因为当我尝试我认为这可能意味着什么时:

def foo = bar
Run Code Online (Sandbox Code Playgroud)

我收到一个错误

缺少方法栏的参数(a:A)

无法解析具有此类签名的参考栏.

dk1*_*k14 7

首先,如果你想为方法创建一个"别名",那就足够了:

scala> val foo = bar(_) //val instead of def, still warning from Idea
foo: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)

其次,这应该删除Idea的警告:

scala> val foo = bar _
foo: Int => Int
Run Code Online (Sandbox Code Playgroud)

实际上,它不仅仅是别名 - 您的方法会转换为函数(eta-expansion).你不能只指定方法(编译时实体),因为编译器会期望参数 - 你需要先将它转换为一个函数(使用下划线).有时它在编译器需要函数时自动完成:

scala> val foo: Int => Int = bar
foo: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)

所以这可能是Idea想要你的.在其他情况下 - 您必须_明确使用eta-expansion运算符().

PS/1.def foo = bar(_)(def而不是val)没有任何意义,因为它每次都会返回新的(但相同的)函数val(或者lazy val是安全的NullPointerException)只返回一次.

PS/2.和之间区别在于,首先是部分应用的功能(自动进行eta扩展),这意味着让我们说:(_)__

scala> def bar(a: Int, b: Int) = a
bar: (a: Int, b: Int)Int

scala> def foo = bar _
foo: (Int, Int) => Int

scala> def foo = bar(_)
<console>:8: error: missing parameter type for expanded function ((x$1) => bar(x$1))
       def foo = bar(_)
                     ^
<console>:8: error: not enough arguments for method bar: (a: Int, b: Int)Int.
Unspecified value parameter b.
       def foo = bar(_)
                    ^

scala> def foo = bar(_, _)
foo: (Int, Int) => Int
Run Code Online (Sandbox Code Playgroud)

你必须指定,bar(_, _)因为有两个参数.


bjf*_*her 5

这是 IntelliJ 的建议。如果您点击建议中的“更多”,您将看到以下内容(抱歉,这是图形,我无法复制文本):

在此输入图像描述

您可以忽略或使用bar _代替bar(_)