Function 定义f(x:Int)=x+;1和val f=(x:Int)=>;x+;1英寸斯卡拉

Function 定义f(x:Int)=x+;1和val f=(x:Int)=>;x+;1英寸斯卡拉,function,scala,syntax,definition,Function,Scala,Syntax,Definition,我是Scala的新手,在理解这一点上遇到了问题。为什么同一个概念有两个语法,但没有一个更有效或更短(仅仅从类型的角度来看,可能它们的行为不同——这就是我要问的) 在Go中,类似物有一个实际的区别——不能向前引用分配给变量的lambda,但可以从任何地方引用命名函数。如果我理解正确,Scala会将这两个变量混合在一起:您可以向前引用任何变量(如果我错了,请纠正我) 请注意,这个问题不是重复的 我知道def在每次引用/调用=后对表达式求值,而val只求值一次。但这是不同的,因为val定义中的表达式

我是Scala的新手,在理解这一点上遇到了问题。为什么同一个概念有两个语法,但没有一个更有效或更短(仅仅从类型的角度来看,可能它们的行为不同——这就是我要问的)

在Go中,类似物有一个实际的区别——不能向前引用分配给变量的lambda,但可以从任何地方引用命名函数。如果我理解正确,Scala会将这两个变量混合在一起:您可以向前引用任何变量(如果我错了,请纠正我)


请注意,这个问题不是重复的

我知道
def
在每次引用/调用
=
后对表达式求值,而
val
只求值一次。但这是不同的,因为
val
定义中的表达式的计算结果是函数


它也不是的复制品


这个问题涉及Scala的语法,而不是直接询问函数和方法之间的区别。尽管答案可能在内容上相似,但在这个网站上澄清这一点仍然很有价值。

有三个主要区别(据我所知):

1.内部代表 函数表达式(又称匿名函数或lambda)在生成的字节码中表示为任何
函数
特征的实例。这意味着函数表达式也是对象。另一方面,方法定义是JVM上的第一类公民,具有特殊的字节码表示。如果没有分析,很难判断这对性能的影响

2.引用语法 对函数和方法的引用具有不同的语法。当您想将方法的引用作为参数发送到代码的其他部分时,不能只说
foo
。你必须说
foo.
。有了函数,你只需说
foo
,事情就会按预期的方式进行。语法
foo
有效地将对
foo
的调用包装在匿名函数中

3.泛型支持 方法支持类型参数化,函数不支持。例如,无法使用函数值表示以下内容:

def identity[A](a: A): A = a
最接近的是此,但它会丢失类型信息:

val identity = (a: Any) => a

作为Ionut第一点的延伸,它可能值得一看

根据我的理解,您描述的函数实例(即。
valf=(x:Int)=>x+1
)扩展了
Function1
类。这意味着函数实例比定义方法消耗更多内存。方法是JVM固有的,因此可以在编译时确定。函数的明显成本是它的内存消耗,但随之而来的是附加的好处,如与其他函数对象的组合


如果我理解正确的话,
def
s和lambdas可以一起工作的原因是函数类有一个自类型
(T1)⇒ R
由其
apply()
方法暗示。(至少我认为是这样的,如果我错了,请纠正我)。然而,这只是我自己的猜测。下面肯定会有一些额外的编译器魔法,以实现方法和函数的互操作性

Scala在某种程度上受到JVM的限制。方法是本地的,而函数不是,因此Scala编译器在某种意义上比简单的JVM方法要做更多的工作来实现一流的函数。严格来说,两种方法都不比另一种更有效。Scala中的真函数有各种开销,而不仅仅是方法。我知道
def
ined函数是作为方法实现的,函数文本是作为对象使用
apply
方法实现的。但我想问的是,它们是否可以互换使用。但我想这回答了关于有两个独立的语法的部分…def foo(x:Int)可能的重复:Int=x+1。列表(1,2,3).map(foo)。不需要foo()?@AndrewCassidy否,这称为eta扩展,scalar将自动执行此操作(将方法转换为一级函数)@AlexIv您能否编辑答案以提供需要eta扩展的示例以及在何处可以使用它?