通过一些代码,我遇到了函数
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] = _ + _
使用前一种方法有什么好处吗?
答案 0 :(得分: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 is an interface而言。当你创建一个基于trait编译器的类时,可以从trait的伴随对象生成简单的实现调用方法。
FunctionN
在Int
,Long
和Double
参数上最多有两个参数specialized
,结果类型参数另外专门用于{{1 },Unit
和Float
。这意味着Boolean
您将获得54种Function2
方法(名称为apply
)。
使用lambda版本时,您使用的是抽象类apply$mcZDD$sp
。所有方法都在此类中生成。只覆盖那些必要的东西。 lambda(scala.runtime.AbstractFunction2
)的类文件大小为 1012字节。不到1kB。
如果ClassName$anonfun$1.class
,所有方法都是在匿名类中生成的。匿名类(new Function2
)的类文件大小约为 20 kB 。
对于ClassName$anon$1.class
(非专业),差异不是很大:Function3
vs 1.1kB
,但{0}参数的1.7kB
是最常见的lambdas。没有FunctionN
字节码大小将是巨大的。