2

通过一些代码,我遇到了这个函数

def sum(): Function2[Double, Double, Double] = 
  new Function2[Double, Double, Double] {
    def apply(t1: Double, t2: Double): Double = t1 + t2;
  }

这与简单得多的声明有何不同,

def sum(): Function2[Double, Double, Double] = _ + _

使用前一种方法有什么好处吗?

4

1 回答 1

2

可读性

详细版本对于开发人员来说非常清楚Java。它看起来几乎像 Java 中的匿名类。所以它可以用来解释 lambdas。这是详细版本的唯一优点。

REPL 支持

REPL 有一点点不同,但没什么用处:

scala> new Function2[Double, Double, Double] {
     |   def apply(t1: Double, t2: Double): Double = t1 + t2;
     | }
res0: java.lang.Object with (Double, Double) => Double = <function2>

scala> val sum: (Double, Double) => Double = _ + _
sum: (Double, Double) => Double = <function2>

字节码大小

jvm trait 而言是一个 interface。当您创建基于 trait 的类时,编译器会通过从 trait 的伴随对象简单调用实现来生成方法。

FunctionN最多两个参数的特征是specializedonInt和参数LongDouble结果类型参数另外专门用于Unit和。这意味着您将获得 54 种附加方法(命名为)。FloatBooleanFunction2applyapply$mcZDD$sp

使用 lambda 版本,您正在使用 abstract class scala.runtime.AbstractFunction2。所有方法都在这个类中生成。仅覆盖那些必要的。ClassName$anonfun$1.classlambda( ) 的类文件大小为1012 字节。小于 1kB。

如果new Function2所有方法都是在匿名类中生成的。匿名类 ( ClassName$anon$1.class) 的类文件大小约为20 kB

对于Function3(不是专门的)差异不是那么大:1.1kBvs 1.7kB,但FunctionN具有 0-2 个参数是最常见的 lambdas。没有AbstractFunctionN字节码大小将是巨大的。

于 2013-06-25T18:35:37.287 回答