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

时间:2015-01-12 21:09:57

标签: scala currying

简介

在我正在使用的外部库中,类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在班级顶部定义:

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)

为什么呢?我应该改变什么才能使它发挥作用?

1 个答案:

答案 0 :(得分:0)

onItemClick[U]的参数是Function4,即一个带有四个参数的函数,详见类型参数。当你写这个表示法时:

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

您正在创建一个几乎正确签名的匿名Function4。我不认为这应该编译。你确定吗?问题是onClick的返回类型为Int,而onItemClick的参数的返回类型为V<: android.widget.AdapterView[_],可能与{Int不兼容1}}。

使用此表示法时:

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