Scala中的Currying与匿名函数

fzsnzjdm  于 4个月前  发布在  Scala
关注(0)|答案(1)|浏览(42)

我比较了在Scala中定义higher-order function的两种方法:

def f1(elem: Int)(other: Int) = (elem == other)

def f2(elem: Int) = (other: Int) => (elem == other)

字符串
第一个使用currying,第二个使用anonymous function
我想知道这两种方法在Scala如何实现它们方面有什么区别,如果有的话,哪个版本更好?

备注:Scala现在已经停止使用第一种方法,因为它支持 * 多参数列表 *。查看链接文档了解更多细节。

j2qf4p5b

j2qf4p5b1#

实现与Scala编译器有很大的不同。curry版本通过取消curry参数来编译为Java方法:

def f1(elem: Int, other: Int): Boolean = elem.==(other);

字符串
第二个版本是一个返回匿名函数(Function1)的方法,所以它们的签名完全不同。尽管它们经常在Scala代码中互换使用,但在第二个版本中生成的代码要多得多:

def f2(elem: Int): Function1 = (new <$anon: Function1>(elem): Function1);

  @SerialVersionUID(value = 0) final <synthetic> class anonfun$f2$1 extends scala.runtime.AbstractFunction1$mcZI$sp with Serializable {
    final def apply(other: Int): Boolean = anonfun$f2$1.this.apply$mcZI$sp(other);
    <specialized> def apply$mcZI$sp(other: Int): Boolean = anonfun$f2$1.this.elem$1.==(other);
    final <bridge> <artifact> def apply(v1: Object): Object = scala.Boolean.box(anonfun$f2$1.this.apply(scala.Int.unbox(v1)));
    <synthetic> <paramaccessor> private[this] val elem$1: Int = _;
    def <init>(elem$1: Int): <$anon: Function1> = {
      anonfun$f2$1.this.elem$1 = elem$1;
      anonfun$f2$1.super.<init>();
      ()
    }
  }


我只会在我明确希望使用Function1对象的情况下考虑使用第二个版本。然而,我个人倾向于使用curried版本,因为你仍然可以在部分应用第一个版本的情况下获得Function1。curried版本同样强大,但不会在你不需要的时候创建Function1对象。

scala> f1(1) _
res1: Int => Boolean = <function1>

相关问题