如何缩短将函数作为参数传递的语法?

How to shorten the syntax of passing a function as a parameter?

简介

在我使用的外部库中,class org.scaloid.common.TraitAdapterView 包含函数 onItemClick 定义为:

@scala.inline
  def onItemClick[U](
     f : scala.Function4[android.widget.AdapterView[_], 
                         android.view.View, 
                         scala.Int, 
                         scala.Long, U]) : V =
     { /* compiled code */ }

其中 V 定义在 class 的顶部:

trait TraitAdapterView[V <: android.widget.AdapterView[_]]

现在进入实际问题。

我在我的代码中定义了以下函数:

def onClick(parent:AdapterView[_] , view:View, position:Int, id:Long) = 3

我可以打电话给

listView.onItemClick((a, b, c, d) => onClick(a, b, c, d))

但以下工作:

listView.onItemClick(onClick)

为什么?我应该更改什么才能使其正常工作?

onItemClick[U] 的参数是一个 Function4,即一个带有四个参数的函数,如类型参数所详述。当你写这个符号时:

(a, b, c, d) => onClick(a, b, c, d)

您正在创建一个签名几乎正确的匿名 Function4。我认为这不应该编译。你确定是吗?问题是 onClick 的 return 类型是 IntonItemClick 的参数预期的 return 类型是 V<: android.widget.AdapterView[_] 这很可能与 Int.

不兼容

当您使用此表示法时:

onClick

您通常会调用 onClick 并将其结果提供给 onItemClick 函数,但由于缺少参数,Scala 编译器应将其解释为函数引用。由于 onClick 的结果与 onItemClick 的参数不兼容,您应该得到一个错误。你能为你得到的错误包括你的编译器输出吗?

当您使用此表示法时:

onClick _

您正在引用名为 onClick 的函数并将其传递给 onItemClick。由于 onClick 是 Function4 的正确类型(假设结果类型兼容),它应该可以工作。

为了您的兴趣,请考虑这个 REPL 会话:

scala> def foo(f: Function1[Int,Int]) : Int = f(1)
foo: (f: Int => Int)Int
scala> def bar(i: Int) : Int = 3
bar: (i: Int)Int
scala> foo(bar)
res0: Int = 3
scala> foo(bar _)
res1: Int = 3
scala> foo((i) => bar(i))
res2: Int = 3