Function 为什么Scala类方法不是一流公民?
我刚开始使用Scala,正在修改工作表。例如:Function 为什么Scala类方法不是一流公民?,function,scala,methods,Function,Scala,Methods,我刚开始使用Scala,正在修改工作表。例如: def merp(str: String) : String = s"Merrrrrrrp $str" val merp2 = (str: String) => s"Merrrrrrrp $str" val merp3 = (str: String) => merp(str) val merp4 = merp _ merp("rjkghleghe") merp4("rjkghleghe") 以及相应的工作表结果: merp: merp
def merp(str: String) : String = s"Merrrrrrrp $str"
val merp2 = (str: String) => s"Merrrrrrrp $str"
val merp3 = (str: String) => merp(str)
val merp4 = merp _
merp("rjkghleghe")
merp4("rjkghleghe")
以及相应的工作表结果:
merp: merp[](val str: String) => String
merp2: String => String = <function1>
merp3: String => String = <function1>
merp4: String => String = <function1>
res0: String = Merrrrrrrp rjkghleghe
res1: String = Merrrrrrrp rjkghleghe
工作表结果:
intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16
merp3
李>
merp4
也是一个,还是有点像etabstractor
工作?Scala正在悄悄地用intCombiner
取代intCombiner吗
理论上的,计算机科学的答案是受欢迎的,因为是指针到任何相关的问题。谢谢 它与
etaAbstractor
一起工作的原因是编译器可以推断出需要函数(而不是函数调用)
如果我不得不猜测为什么在无法推断函数类型的情况下需要下划线,我认为这是为了改进常见错误类的错误报告(在需要调用的情况下获取函数)。但是,这只是一个猜测
在JVM中,方法不是对象,而一级函数必须是对象。因此,必须将方法装箱到对象中才能将其转换为函数。免责声明:我不是计算机科学家,但我会尝试猜测:
apply()
method),您正在创建一个闭包。此过程称为eta扩展valmerp3:(String=>String)=merp
merp4
也是eta扩展Scala的设计和实现与Java/JVM在许多方面的兼容性密切相关——我敢肯定,如果没有这一点,两者之间的差别会很小,但你必须问问Martin(我想他偶尔会访问),或者找到一些早期的impl注释。虽然它们可以很容易地用
method.
进行“升级”。Python和JavaScript的方法都是一流的函数,所以#1是“在Scala(和Java中)…。@user2864740在Python中未绑定的方法不能被调用,所以在我看来它不是一流的函数。指定一个绑定方法看起来像是引擎盖下的eta扩展。如果在函数中使用this
,Javascript也会出现同样的问题,只是在this
的值中会出现未定义的,而不是错误。仍然存在的问题是,方法不是一流的值,而是通过名称(或)调用的“定义的表现形式”。维护上下文(或不维护上下文)不会影响他们的公民身份:或者根本的实现差异。非常感谢规范的链接。为了完成Q#1,我推测这是一个语言设计决策,其结果是Scala代码如何被翻译到JVM中。具体地说,方法(是没有值的抽象)可以在编译时最终确定,而函数
(作为对象,其伴随的闭包是动态树结构)只能在运行时创建。要使方法具体化,必须创建函数
对象。这可能会对性能产生影响,因此要求程序员显式地创建该对象而不是误导是一个好的决定。
intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16